HDU 3966 Aragorn's Story 树链剖分

Link: http://acm.hdu.edu.cn/showproblem.php?pid=3966

这题注意要手动扩栈。

这题我交g++无限RE,即使手动扩栈了,但交C++就过了。

  1 #pragma comment(linker, "/STACK:1024000000,1024000000")
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <iostream>
  5 #include <algorithm>
  6 #include <string>
  7 #include <vector>
  8 #include <map>
  9 using namespace std;
 10 const int maxn = 5e4+5;
 11 #ifdef WIN32
 12     #define LL __int64
 13 #else
 14     #define LL long long
 15 #endif
 16 
 17 
 18 int A[maxn],totw;
 19 struct node
 20 {
 21     int fa,son,top,w,size,deep;
 22 }tree[maxn];
 23 vector<int> vt[maxn];
 24 int tr[maxn];
 25 
 26 void dfs_1(int p,int last,int de)
 27 {
 28     tree[p].son = -1;
 29     tree[p].fa = last;
 30     tree[p].deep = de;
 31     tree[p].size = 1;
 32     int num = vt[p].size();
 33     for(int i = 0;i < num;++i)
 34         if(vt[p][i] != last)
 35         {
 36             dfs_1(vt[p][i],p,de+1);
 37             tree[p].size += tree[vt[p][i]].size;
 38             if(-1 == tree[p].son || tree[vt[p][i]].size > tree[tree[p].son].size)
 39                 tree[p].son = vt[p][i];
 40         }
 41 }
 42 void dfs_2(int p,int top)
 43 {
 44     tree[p].w = ++totw;
 45     tree[p].top = top;
 46     if(tree[p].son != -1)
 47         dfs_2(tree[p].son,top);
 48     else return ;
 49     int num = vt[p].size();
 50     for(int i = 0;i < num;++i)
 51     {
 52         if(vt[p][i] != tree[p].fa && vt[p][i] != tree[p].son)
 53             dfs_2(vt[p][i],vt[p][i]);
 54     }
 55 }
 56 
 57 void sol()
 58 {
 59     totw = 0;
 60     memset(tr,0,sizeof(tr));
 61     memset(tree,0,sizeof(tree));
 62     dfs_1(1,0,1);
 63     dfs_2(1,1);
 64 }
 65 int lowbit(int x)
 66 {
 67     return x & (-x);
 68 }
 69 int query(int p)
 70 {
 71     p = tree[p].w;
 72     int tot = 0;
 73     while(p >= 1)
 74     {
 75         tot += tr[p];
 76         p -= lowbit(p);
 77     }
 78     return tot;
 79 }
 80 void add(int n,int p,int d)
 81 {
 82     while(p <= n)
 83     {
 84         tr[p] += d;
 85         p += lowbit(p);
 86     }
 87 }
 88 void update_sec(int n,int u,int v,int d)
 89 {
 90     if(tree[u].w > tree[v].w) swap(u,v);
 91     add(n,tree[u].w,d);
 92     add(n,tree[v].w+1,-d);
 93 }
 94 void update(int n,int u,int v,int d)
 95 {
 96     /*
 97     u,v不断靠近根结点
 98     */
 99     while(tree[u].top != tree[v].top)
100     {
101         if(tree[tree[u].top].deep < tree[tree[v].top].deep) swap(u,v);
102         update_sec(n,tree[u].top,u,d);
103         u = tree[tree[u].top].fa;
104     }
105     update_sec(n,u,v,d);
106 }
107 
108 int main()
109 {
110 //    freopen("in.txt","r",stdin);
111     int n,m,p;
112     while(scanf("%d%d%d",&n,&m,&p)!=EOF)
113     {
114         for(int i = 1;i <= n;++i)
115             scanf("%d",&A[i]);
116         for(int i = 1;i <= n;++i)
117             vt[i].clear();
118         int x,y;
119         for(int i = 0;i < m;++i)
120         {
121             scanf("%d%d",&x,&y);
122             vt[x].push_back(y);
123             vt[y].push_back(x);
124         }
125         sol();
126         char oper[5];
127         while(p--)
128         {
129             scanf("%s",oper);
130             int x,y,z;
131             if('Q' == oper[0])
132             {
133                 scanf("%d",&x);
134                 printf("%d
",A[x] + query(x));
135             }
136             else if('I' == oper[0])
137             {
138                 scanf("%d%d%d",&x,&y,&z);
139                 update(n,x,y,z);
140             }
141             else if('D' == oper[0])
142             {
143                 scanf("%d%d%d",&x,&y,&z);
144                 update(n,x,y,-z);
145             }
146         }
147     }
148     return 0;
149 }
View Code
原文地址:https://www.cnblogs.com/xiaxiaosheng/p/4746570.html