zoukankan      html  css  js  c++  java
  • 块状树

    BZOJ4765

    将树按深度分为sqrt(n)条可相互重叠的链

    修改时在树上链块外在全局的分块上修改,块内打标记。O(sqrt(n))

    询问时先取分快答案,然后枚举所有链,对答案的贡献为标记之和*链锁对的位置在询问中的数量

    #include <cstdio>
    #include <iostream>
    #include <cmath>
    #define ULL unsigned long long 
    using namespace std;
    
      int maxdep[110001],dep[110001],nd[110001],next[210001],des[210001],blsize;
      int speid[110001],cnt,spe[110001],n,m,root,fa[110001],pre[501][110001],fa_spe[110001];
      ULL ori[110001],a[110001],sum[110001],toadd[110001];
      int bt[110001];
    
      void addedge(int x,int y){
          next[++cnt]=nd[x];des[cnt]=y;nd[x]=cnt;
      }
    
      void dfs1(int po){
          maxdep[po]=dep[po];
          bt[po]=1;
          for (int p=nd[po];p!=-1;p=next[p])
          if (!bt[des[p]]){
            dep[des[p]]=dep[po]+1;
            fa[des[p]]=po;
            dfs1(des[p]);
            ori[po]+=ori[des[p]];
            maxdep[po]=max(maxdep[po],maxdep[des[p]]);
        }
        
        if (maxdep[po]-dep[po]>=blsize){
          speid[po]=++cnt;
          spe[po]=1;maxdep[po]=dep[po];    
        }
      }
    
      int main(){
          scanf("%d%d",&n,&m);
          for (int i=1;i<=n;i++) scanf("%llu",&ori[i]),a[i]=ori[i],nd[i]=-1;
          for (int i=1;i<=n;i++){
            int t1,t2;
            scanf("%d%d",&t1,&t2);
            if (t1==0) root=t2;else
            if (t2==0) root=t1;else
            addedge(t1,t2),addedge(t2,t1);
        }
        
        blsize=sqrt(n);
        dep[root]=1;
        cnt=0;
        dfs1(root);
        
        spe[0]=1;
        for (int i=1;i<=n;i++)
          if (spe[i]){
            int po=i;pre[speid[i]][po]=1;po=fa[po];
            while (!spe[po]){
              pre[speid[i]][po]++;
              po=fa[po];    
            }
            for (int j=1;j<=n;j++)
              pre[speid[i]][j]+=pre[speid[i]][j-1];
            fa_spe[i]=po;    
          }
          
        for (int i=1;i<=n;i++) sum[i/blsize+1]+=ori[i];
        
        int quecnt=0;
        for (int i=1;i<=m;i++){
          ULL t1,t2,t3;
          scanf("%llu%llu%llu",&t1,&t2,&t3);
          if (t1==2){
              quecnt++;
              ULL ans=0;
              for (int i=1;i<=cnt;i++) ans+=toadd[i]*(ULL)(pre[i][t3]-pre[i][t2-1]);
              while (t2%blsize&&t2<=t3) ans+=ori[t2],t2++;
              while (t3%blsize&&t3>=t2) ans+=ori[t3],t3--;
            if (t3>=t2) ans+=ori[t3--];
              if (t3>=t2) for (int i=t2/blsize+1;i<=t3/blsize+1;i++) ans+=sum[i];
              printf("%llu
    ",ans);
          }else{
              ULL su=t3-a[t2];a[t2]=t3;
              int po=t2;
              while (!spe[po]){
                ori[po]+=su;
              sum[po/blsize+1]+=su;
              po=fa[po];    
            }
            while (po){
              toadd[speid[po]]+=su;
              po=fa_spe[po];
            }
          }    
        }
      }
  • 相关阅读:
    Java控制台五子棋编码学习
    Java Web基础
    JavaScript Unit Test with Mocha
    Cross-browser Testing Tool
    GRIDVIEW 控件
    C# .net ACCESS 网页增删改查 --留言板
    在一般处理文件中访问Session需要添加IRequiresSessionState(转载)
    win7 IIS7 发布网站 出现 "处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误"
    http://www.cnblogs.com/hanshuhe/archive/2012/08/30/vss.html
    win 7 配置 IIS
  • 原文地址:https://www.cnblogs.com/zhujiangning/p/6529292.html
Copyright © 2011-2022 走看看