zoukankan      html  css  js  c++  java
  • p3676 小清新数据结构题

    分析

     树状数组做区间加时要用到差分的思想

     代码

    #include<bits/stdc++.h>
    using namespace std;
    #define li long long
    li Ans;
    vector<int>v[200100];
    inline int lb(int x){return x&(-x);}
    int n,m,q,cnt,d1[200100],d2[200100],id[200100],w[200100],c[200100];
    int dep[200100],fa[200100],son[200100],siz[200100],ac[200100],pl[200100];
    inline void add(int x,int k){int wh=x*k;while(x<=n)d1[x]+=k,d2[x]+=wh,x+=lb(x);}
    inline li qurey(int x){li res=0,wh=x+1;while(x)res+=1ll*wh*d1[x]-d2[x],x-=lb(x);return res;}
    inline void dfs(int x,int f){
        int mx=0;
        siz[x]=1;
        dep[x]=dep[f]+1;
        fa[x]=f;
        for(int i=0;i<v[x].size();i++)
          if(v[x][i]!=f){
              dfs(v[x][i],x);
              w[x]+=w[v[x][i]];
              siz[x]+=siz[v[x][i]];
              if(siz[v[x][i]]>mx){
                mx=siz[v[x][i]];
                son[x]=v[x][i];
            }
          }
        Ans+=1ll*w[x]*w[x];
    }
    inline void dfs2(int x,int acc){
        ac[x]=acc;
        id[x]=++cnt;
        pl[cnt]=x;
        add(cnt,w[x]-w[pl[cnt-1]]);
        if(son[x])dfs2(son[x],acc);
        for(int i=0;i<v[x].size();i++)
          if(v[x][i]!=fa[x]&&v[x][i]!=son[x])dfs2(v[x][i],v[x][i]);
    }
    inline void update(int x,int k){
        int sum=0;
        li res=0;
        while(x){
          sum+=id[x]-id[ac[x]]+1;
          res+=qurey(id[x])-qurey(id[ac[x]]-1);
          add(id[ac[x]],k),add(id[x]+1,-k);
          x=fa[ac[x]];
        }
        Ans+=1ll*k*(sum*k+(res<<1));
    }
    inline li que(int x){
        int sum=0;
        li res=0,k=qurey(1);
        while(x){
          sum+=id[x]-id[ac[x]]+1;
          res+=qurey(id[x])-qurey(id[ac[x]]-1);
          x=fa[ac[x]];
        }
        return Ans+k*((sum+1)*k-(res<<1));
    }
    int main(){
        int i,j,k;
        scanf("%d%d",&n,&q);
        for(i=1;i<n;i++){
          int x,y;
          scanf("%d%d",&x,&y);
          v[x].push_back(y);
          v[y].push_back(x);
        }
        for(i=1;i<=n;i++)scanf("%d",&c[i]),w[i]=c[i];
        dfs(1,0);
        dfs2(1,1);
        for(i=1;i<=q;i++){
          int x,y;
          scanf("%d%d",&k,&x);
          if(k==1)scanf("%d",&y),y-=c[x],c[x]+=y,update(x,y);
            else printf("%lld
    ",que(x));
        } 
        return 0;
    }

     

  • 相关阅读:
    证券市场主体
    证券投资基金
    1.监控系统的重要性
    1.五种世界顶级思维-20190303
    【四校联考】【比赛题解】FJ NOIP 四校联考 2017 Round 7
    【学长出题】【比赛题解】17-09-29
    【codeforces】【比赛题解】#854 CF Round #433 (Div.2)
    【codeforces】【比赛题解】#851 CF Round #432 (Div.2)
    【算法学习】三分法
    【codeforces】【比赛题解】#849 CF Round #431 (Div.2)
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/11470801.html
Copyright © 2011-2022 走看看