1. 程式人生 > >18寒假第四測

18寒假第四測

a.out modify col 技術 query ini btree out ron

技術分享圖片

技術分享圖片

problem 4 full

技術分享圖片

第一題:裸的樹狀數組

#include <cstdio>

const int N = 100010;
const int M = N + N;

int n, q;
int aa[N];
int head[N], dest[M], last[M], etot;
int in[N], out[N], seq[N], idc;
long long bit[N];

void adde( int u, int v ) {
    etot++;
    dest[etot] = v;
    last[etot] = head[u];
    head[u] 
= etot; } void dfs( int u, int f ) { idc++; in[u] = idc; seq[idc] = u; for( int t = head[u]; t; t = last[t] ) { int v = dest[t]; if( v == f ) continue; dfs( v, u ); } out[u] = idc; } void modify( int pos, int delta ) { for( int i = pos; i <= n; i += i & -i ) bit[i]
+= delta; } long long query( int rg ) { long long rt = 0; for( int i = rg; i; i -= i & -i) { rt += bit[i]; } return rt; } long long query( int lf, int rg ) { return query(rg) - query(lf-1); } int main() { freopen("subtree.in", "r", stdin); freopen("subtree.out"
, "w", stdout); scanf( "%d", &n ); for( int i = 1; i <= n; i++ ) scanf( "%d", aa + i ); for( int i = 1; i < n; i++ ) { int u, v; scanf( "%d%d", &u, &v ); adde( u, v ); adde( v, u ); } idc = 0; dfs(1,1); for( int u = 1; u <= n; u++ ) { modify( in[u], aa[u] ); } scanf( "%d", &q ); while( q-- ) { char ss[100]; int u, d; scanf( "%s", ss ); if( ss[0] == m ) { scanf( "%d%d", &u, &d ); modify( in[u], d ); } else { scanf( "%d", &u ); printf( "%lld\n", query( in[u], out[u] ) ); } } }

第二題:裸的樹剖求LCA

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100005;
int a[maxn],head[maxn * 2],to[maxn * 2],next[maxn * 2];//2倍空間
int son[maxn], f[maxn], siz[maxn], top[maxn], dep[maxn];
int n, tot, idx, m;
void adde(int u, int v){
    ++tot;
    next[tot] = head[u];
    to[tot] = v;
    head[u] = tot;
}

void dfs1(int u,int from){
    siz[u] = 1;
    
    for(int i = head[u]; i; i = next[i]){
        int v = to[i];
        if(v != from){
        
            f[v] = u;
            dep[v] = dep[u] + 1;
            dfs1(v, u);
            siz[u] += siz[v];            
            if(siz[v] > siz[son[u]])
                son[u] = v;
        }
    }
}
void dfs2(int u,int from){
    
    top[u] = from;
    if(son[u])dfs2(son[u], from);
    for(int i = head[u]; i; i = next[i]){
        int v = to[i];
        if(v == f[u] || v == son[u])continue;//f[u] != from    !
        dfs2(v, v);
    }
}

int lca(int u, int v){
    while(top[u] != top[v]){
        if(dep[top[u]] < dep[top[v]])swap(u, v);//dep[top]   !
        u = f[top[u]];
    }
    return dep[u] < dep[v] ? u : v;
}
int main(){
    freopen("dcplca.in","r",stdin);
    freopen("dcplca.out","w",stdout);
    //ios::sync_with_stdio(false);
    cin>>n;
    for(int i = 1; i < n; i++){
        int u, v;
        scanf("%d%d",&u,&v);
        adde(u, v);
        adde(v, u);
    }
    dep[1] = f[1] =1;
    dfs1(1, 1);
    dfs2(1, 1);
    cin>>m;
    for(int i = 1; i <= m; i++){
        int u,v;
        scanf("%d%d",&u,&v);
        printf("%d\n",lca(u, v));
        
    }
}

第三題:線段樹+樹剖

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100005;
long long c[maxn];
int a[maxn],head[maxn * 2],to[maxn * 2],next[maxn * 2];
int son[maxn], in[maxn], out[maxn], f[maxn], siz[maxn], top[maxn], dep[maxn];
int n, tot, idx, m;

void adde(int u, int v){
    ++tot;
    next[tot] = head[u];
    to[tot] = v;
    head[u] = tot;
}

struct SegmentTree{
    struct node{
        long long sum;
        int lazy; 
    };
    node Tree[maxn << 2];
    
    #define ls l, m, v << 1
    #define rs m+1, r, v << 1 | 1
    
    void push_up(int v){

        Tree[v].sum = Tree[v << 1].sum + Tree[v << 1 | 1].sum;
    }
    void push_down(int l,int r,int v){
        int m = (l + r) >> 1;
        Tree[v << 1].sum += 1LL * Tree[v].lazy * (m - l + 1);
        Tree[v << 1].lazy += Tree[v].lazy;
        Tree[v << 1 | 1].sum += 1LL * Tree[v].lazy * (r - m);
        Tree[v << 1 | 1].lazy += Tree[v].lazy;
        
        Tree[v].lazy = 0;
        
    }
    void build(int l = 1, int r = n, int v = 1){
        Tree[v].sum = Tree[v].lazy = 0;
        if(l == r) {
            Tree[v].sum = a[l] * 1LL;
            Tree[v].lazy = 0;
        }
        else {
            int m = (l + r) >> 1;
            build(ls);
            build(rs);
            push_up(v);
        }
    }
    
    void modify(int x,int L,int R,int l = 1, int r = n,int v = 1){
        if(l >= L && r <= R)
            Tree[v].sum += 1LL * x * (r - l + 1), Tree[v].lazy += x;
        else {
            if(Tree[v].lazy)push_down(l,r,v);
            int m = (l + r) >> 1;
            if(L <= m) modify(x,L,R,ls);
            if(R > m) modify(x,L,R,rs);
            push_up(v);
        }
    }

    long long  query(int L,int R,int l = 1, int r = n,int v = 1){
        if(l >= L && r <= R)
            return Tree[v].sum ;
        else {
            if(Tree[v].lazy)push_down(l,r,v);
            int m = (l + r) >> 1;
            long long ans = 0;
            if(L <= m) ans += query(L,R,ls);
            if(R > m) ans += query(L,R,rs);
            return ans;
        }
    }
    
}; 

SegmentTree Tr;

void dfs1(int u,int from){
    siz[u] = 1;
    for(int i = head[u]; i; i = next[i]){
        int v = to[i];
        if(v != from){        
            f[v] = u;
            dep[v] = dep[u] + 1;
            dfs1(v, u);
            siz[u] += siz[v];            
            if(siz[v] > siz[son[u]])
                son[u] = v;
        }
    }
    
}

void dfs2(int u,int from){
    in[u] = ++idx;
    a[idx] = c[u];
    top[u] = from;
    if(son[u])dfs2(son[u], from);
    for(int i = head[u]; i; i = next[i]){
        int v = to[i];
        if(v == f[u] || v == son[u])continue;//f[u] != from !
        dfs2(v, v);
    }
    out[u] = idx;
}

long long lca1(int u, int v){
    long long ans = 0;
    while(top[u] != top[v]){
        if(dep[top[u]] < dep[top[v]])//dep[top]!
            swap(u, v);
        ans += Tr.query(in[top[u]], in[u]);
        u = f[top[u]];
    }
    if(dep[u] < dep[v])swap(u,v);
    ans += Tr.query(in[v], in[u]);
    return  ans;
}

void lca2(int u, int v,int x){
    long long ans = 0;
    while(top[u] != top[v]){
        if(dep[top[u]] < dep[top[v]])//dep[top]!
            swap(u, v);
        Tr.modify(x, in[top[u]], in[u]);
        u = f[top[u]];
    }
    if(dep[u] < dep[v])swap(u,v);
    Tr.modify(x, in[v], in[u]);
}

void init(){
    
    cin>>n;
    for(int i = 1; i <= n; i++)
        scanf("%d",c + i);
    for(int i = 1; i < n; i++){
        int u, v;
        scanf("%d%d",&u,&v);
        adde(u, v);
        adde(v, u);
    }
    dep[1] = f[1] = 1;
    dfs1(1,1);
    dfs2(1,1);
    Tr.build();
}

void work(){
    cin>>m;
    for(int i = 1; i <= m; i++){
        string opt;
        cin>>opt;
        if(opt == "msub"){
            int u,x;
            scanf("%d%d",&u,&x);
            Tr.modify(x,in[u],out[u]);
        }
        if(opt == "mpth"){
            int u,x,v;            
            scanf("%d%d%d",&u,&v,&x);
            lca2(u,v,x);

        }
        if(opt == "qsub"){
            int u;
            scanf("%d",&u);
            cout<<Tr.query(in[u],out[u])<<endl;
        }
        if(opt == "qpth"){
            int u,v;
            scanf("%d%d",&u,&v);
            cout<<lca1(u, v)<<endl;
        }
        
    }
}
int main(){
    freopen("full.in","r",stdin);
    freopen("full.out","w",stdout);
    init();
    work();
}

18寒假第四測