• 18寒假第四测


    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
    ", 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
    ",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();
    }
  • 相关阅读:
    js 字符串indexOf方法封装
    js 冒泡排序
    CSS定位 position的三个属性 elative 、absolute、fixed :
    让父元素能感知浮动的子元素 #用伪元素清除浮动
    三个路由器的连接,中间路由的配置(静态路由)
    IDEA 添加tomcat出错: Error: Environment variable name is not set 我的解决方法
    通过基于AspectJ 注解的方式实现Spring AOP报 can't find referenced pointcut myPointCut 错误,我的解决方法
    C语言fopen函数打开文本文件与二进制文件的区别
    位运算的奇技淫巧 系列1
    位运算例子(以后会逐渐补充)
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/8438322.html
Copyright © 2020-2023  润新知