hdu3966(树链剖分)

update: 2018-01-27

下面的应该是很久之前抄的代码了,,当时应该是费了很大劲弄明白了一点吧=_=||

最近一直再刷数据结构,今天终于刷到树链剖分了,看了一下代码感觉挺清晰的...

具体讲解就看高级数据结构这本书吧,p401,感觉写的很清晰易懂。

 

最近几天最大的感受就是,半年前怎么都搞不明白的东西现在可以轻轻松松看懂了。我想可能就是当时这些东西确实超出了我的理解能力吧,其实后来这半年感觉并没有什么进步,应该就是不知不觉中提升了吧,忽然想起来半年前去看一年前的东西也是一样的感觉。

集训不剩几天了,之后还有别的事情要做呢,加油吧~

 



 

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3966

参考:http://blog.csdn.net/acdreamers/article/details/10594121

 

明天再补代码,,睡觉!!

----------------------------------------------------------------------------------

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<iostream>
  5 using namespace std;
  6 const int maxn=50010;
  7 
  8 struct edge
  9 {
 10     int v,nex;
 11 }e[maxn<<1];
 12 
 13 int n,m,q;
 14 int cur;
 15 int w[maxn],siz[maxn],top[maxn],son[maxn];
 16  // 节点权重  子树节点数   链首        重儿子  
 17 int dep[maxn],f[maxn],order[maxn],tid[maxn];
 18  // 深度        父亲    生成线段     遍历序列编号   
 19 
 20 int head[maxn];
 21 int cnt;
 22 
 23 void init()
 24 {
 25     memset(head,-1,sizeof(head));
 26     memset(son,-1,sizeof(son));
 27     cur=0;
 28     cnt=0;
 29 }
 30 
 31 void adde(int u,int v)
 32 {
 33     e[cnt].v=v;
 34     e[cnt].nex=head[u];
 35     head[u]=cnt++;
 36 }
 37 
 38 
 39 
 40 //树链剖分
 41 void dfs1(int u,int fa,int d)
 42 {
 43     dep[u]=d;
 44     f[u]=fa;
 45     siz[u]=1;
 46     for(int i=head[u];i!=-1;i=e[i].nex)
 47     {
 48         int v=e[i].v;
 49         if(v!=fa)
 50         {
 51             dfs1(v,u,d+1);
 52             siz[u]+=siz[v];
 53             if(son[u]==-1||siz[v]>siz[son[u]])  //更新重儿子
 54                 son[u]=v;
 55         }
 56     }
 57 }
 58 
 59 void dfs2(int u,int tp)
 60 {
 61     top[u]=tp;
 62     tid[u]=++cur;
 63     order[tid[u]]=u;
 64     if(son[u]==-1) return ;
 65     dfs2(son[u],tp);
 66     for(int i=head[u];i!=-1;i=e[i].nex)
 67     {
 68         int v=e[i].v;
 69         if(v!=son[u]&&v!=f[u])
 70             dfs2(v,v);
 71     }
 72 }
 73 
 74 //线段树
 75 #define lson l,m,rt<<1
 76 #define rson m+1,r,rt<<1|1
 77 
 78 int sum[maxn<<2];
 79 int add[maxn<<2];
 80 
 81 void pushup(int rt)
 82 {
 83     sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
 84 }
 85 
 86 void pushdown(int rt,int m)
 87 {
 88     if(add[rt])
 89     {
 90         add[rt<<1]+=add[rt];
 91         add[rt<<1|1]+=add[rt];
 92         sum[rt<<1]+=add[rt]*(m-(m>>1));
 93         sum[rt<<1|1]+=add[rt]*(m>>1);
 94         add[rt]=0;
 95     }
 96 }
 97 
 98 void build(int l,int r,int rt)
 99 {
100     add[rt]=0;
101     if(l==r)
102     {
103         sum[rt]=w[order[l]];
104         return ;
105     }
106     int m=(l+r)>>1;
107     build(lson);
108     build(rson);
109     pushup(rt);
110 }
111 void update(int L,int R,int c,int l,int r,int rt)
112 {
113     if(L<=l&&r<=R)
114     {
115         add[rt]+=c;
116         sum[rt]+=c*(r-l+1);
117         return ;
118     }
119     pushdown(rt,r-l+1);
120     int m=(l+r)>>1;
121     if(L<=m) update(L,R,c,lson);
122     if(R>m) update(L,R,c,rson);
123     pushup(rt);
124 }
125 int query(int pos,int l,int r,int rt)
126 {
127     if(l==r) return sum[rt];
128     pushdown(rt,r-l+1);
129     int m=(l+r)>>1;
130     int ans=0;
131     if(pos<=m) ans=query(pos,lson);
132     else ans=query(pos,rson);
133     pushup(rt);
134     return ans;
135 }
136 
137 void change(int x,int y,int c)
138 {
139     while(top[x]!=top[y])  //不在一条链
140     {
141         if(dep[top[x]]<dep[top[y]]) swap(x,y);  
142         update(tid[top[x]],tid[x],c,1,n,1);   // 更新链首深度大的那一条链
143         x=f[top[x]];  // x所在链已更新完,将x记为x与y连接的那个点
144     }
145     if(dep[x]>dep[y]) swap(x,y);
146     update(tid[x],tid[y],c,1,n,1);
147 }
148 
149 int main()
150 {
151     char op[3];
152     int a,b,c;
153     int u,v;
154     while(scanf("%d%d%d",&n,&m,&q)!=EOF)
155     {
156         init();
157         for(int i=1;i<=n;i++)
158             scanf("%d",&w[i]);
159         for(int i=1;i<=m;i++)
160         {
161             scanf("%d%d",&u,&v);
162             adde(u,v);
163             adde(v,u);
164         }
165         dfs1(1,0,0);
166         dfs2(1,1);
167         build(1,n,1);
168         while(q--)
169         {
170             scanf("%s",op);
171             if(op[0]=='Q')
172             {
173                 scanf("%d",&a);
174                 printf("%d\n",query(tid[a],1,n,1));
175             }
176             else
177             {
178                 scanf("%d%d%d",&a,&b,&c);
179                 if(op[0]=='D') c=-c;
180                 change(a,b,c);
181             }
182         }
183     }
184     return 0;
185 }

 

posted @ 2017-04-12 00:29  yijiull  阅读(139)  评论(0编辑  收藏  举报