HDU3966 Aragorn's Story 树链剖分+线段树

区间更新,单点查询,,,,奇葩,HDU上强行加了扩栈才过。

  1 #pragma comment(linker, "/STACK:1024000000,1024000000")
  2 
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <algorithm>
  6 using namespace std;
  7 #define lson l,m,rt<<1
  8 #define rson m+1,r,rt<<1|1
  9 const int maxn = 50005;
 10 struct edge
 11 {
 12     int v,next;
 13 }e[maxn*2];
 14 int head[maxn],cnt,sum[maxn<<2],lazy[maxn<<2],val[maxn];
 15 int siz[maxn],son[maxn],fa[maxn],top[maxn],tid[maxn],dep[maxn],lable;
 16 int n,m,p;
 17 void init()
 18 {
 19     memset(head,-1,sizeof(head));
 20     memset(lazy,0,sizeof(lazy));
 21     memset(sum,0,sizeof(sum));
 22     cnt = lable = 0;
 23 }
 24 void add(int u,int v)
 25 {
 26     e[cnt].v = v;
 27     e[cnt].next = head[u];
 28     head[u] = cnt++;
 29 }
 30 void find_heavy(int rt,int father,int depth)
 31 {
 32     fa[rt] = father;
 33     siz[rt] = 1;
 34     son[rt] = 0;
 35     dep[rt] = depth;
 36     int maxsize = 0;
 37     for(int i = head[rt];i!=-1;i = e[i].next)if(e[i].v!=father)
 38     {
 39         find_heavy(e[i].v,rt,depth+1);
 40         siz[rt]+=siz[e[i].v];
 41         if(siz[rt]>maxsize)
 42             maxsize = siz[rt],son[rt] = e[i].v;
 43     }
 44 }
 45 void connect(int rt,int anc)
 46 {
 47     tid[rt] = ++lable;
 48     top[rt] = anc;
 49     if(son[rt])connect(son[rt],anc);
 50     for(int i = head[rt];i!=-1;i = e[i].next)
 51         if(e[i].v!=fa[rt]&&e[i].v!=son[rt])
 52             connect(e[i].v,e[i].v);
 53 }
 54 void pushup(int rt)
 55 {
 56     sum[rt] = sum[rt<<1]+sum[rt<<1|1];
 57 }
 58 void pushdown(int rt,int m)
 59 {
 60     if(lazy[rt])
 61     {
 62         lazy[rt<<1]+=lazy[rt];
 63         lazy[rt<<1|1]+=lazy[rt];
 64         sum[rt<<1]+=lazy[rt]*(m-(m>>1));
 65         sum[rt<<1|1]+=lazy[rt]*(m>>1);
 66         lazy[rt] = 0;
 67     }
 68 }
 69 void update(int L,int R,int v,int l,int r,int rt)
 70 {
 71     if(L<=l&&r<=R){
 72         lazy[rt]+=v;
 73         sum[rt]+=v*(r-l+1);
 74         return;
 75     }
 76     pushdown(rt,r-l+1);
 77     int m = (l+r)>>1;
 78     if(L<=m)update(L,R,v,lson);
 79     if(m<R)update(L,R,v,rson);
 80     pushup(rt);
 81 }
 82 void change(int x,int y,int c)
 83 {
 84     while(top[x]!=top[y])
 85     {
 86         if(dep[top[x]]<dep[top[y]])swap(x,y);
 87         update(tid[top[x]],tid[x],c,1,n,1);
 88         x = fa[top[x]];
 89     }
 90     if(dep[x]>dep[y])swap(x,y);
 91     update(tid[x],tid[y],c,1,n,1);
 92 }
 93 int query(int L,int R,int l,int r,int rt)
 94 {
 95     if(L<=l&&r<=R)return sum[rt];
 96     pushdown(rt,r-l+1);
 97     int m = (l+r)>>1,ret = 0;
 98     if(L<=m)ret+=query(L,R,lson);
 99     if(m<R)ret+=query(L,R,rson);
100     return ret;
101 }
102 int main()
103 {
104     //freopen("in.txt","r",stdin);
105     while(~scanf("%d%d%d",&n,&m,&p))
106     {
107         for(int i = 1;i<=n;++i)scanf("%d",&val[i]);
108         init();
109         for(int i = 1;i<=m;++i)
110         {
111             int u,v;
112             scanf("%d%d",&u,&v);
113             add(u,v);add(v,u);
114         }
115         find_heavy(1,1,1);
116         connect(1,1);
117         for(int i = 1;i<=n;++i)update(tid[i],tid[i],val[i],1,n,1);
118         while(p--)
119         {
120             char s[2];int a,b,c;
121             scanf("%s",s);
122             if(s[0]=='I'){
123                 scanf("%d%d%d",&a,&b,&c);
124                 change(a,b,c);
125             }
126             else if(s[0]=='D'){
127                 scanf("%d%d%d",&a,&b,&c);
128                 change(a,b,-c);
129             }
130             else{
131                 scanf("%d",&a);
132                 printf("%d\n",query(tid[a],tid[a],1,n,1));
133             }
134         }
135     }
136     return 0;
137 }

 

posted on 2015-07-25 11:55  round_0  阅读(177)  评论(0编辑  收藏  举报

导航