Advertisement
Tranvick

Hldot(usaco2011,dec,Grassplainting)

Apr 23rd, 2012
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.74 KB | None | 0 0
  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <vector>
  4. #define forn(I,B) for (int I=1;I<=(B);I++)
  5. #define rep(I,B) for (int I=0;I<(B);I++)
  6. #define rwopen(X) freopen(X".in","r",stdin);freopen(X".out","w",stdout)
  7. #define pb push_back
  8.  
  9. using namespace std;
  10.  
  11. typedef vector<int> vi;
  12. const int N=100001;
  13. const int M=200000;
  14. const int L=16;
  15.  
  16. struct tree{
  17.     int l,r,add,sum;
  18. };
  19.  
  20. int ef[M],es[M],next[M],first[N],up[N][L+1],tin[N],tout[N],n,m,c,timer,f[N],cw,where[N],num[N],i,h[N];
  21. bool b[N];
  22. vi ways[N];
  23. vector<tree> RSQ[N];
  24.  
  25. inline void add(int x,int y){
  26.     next[++c]=first[x];first[x]=c;
  27.     es[c]=y;ef[c]=x;
  28.     next[++c]=first[y];first[y]=c;
  29.     es[c]=x;ef[c]=y;
  30. }
  31.  
  32. inline bool upper(int a,int b){
  33.     return tin[a]<=tin[b] && tout[a]>=tout[b];
  34. }
  35.  
  36. void calc_up(int v,int p=1){
  37.     up[v][0]=p;f[v]=1;
  38.     tin[v]=++timer;
  39.     for (i=1;i<=L;i++) up[v][i]=up[up[v][i-1]][i-1];
  40.     for (h[v]=first[v];h[v];h[v]=next[h[v]]) if (es[h[v]]!=p){
  41.         calc_up(es[h[v]],v);
  42.         f[v]+=f[es[h[v]]];
  43.     }
  44.     for (h[v]=first[v];h[v];h[v]=next[h[v]]) if (es[h[v]]!=p && f[es[h[v]]]>f[v]/2){
  45.         b[v]=1;
  46.         break;
  47.     }
  48.     tout[v]=++timer;
  49. }
  50.  
  51. inline int lca(int a,int b){
  52.     if (upper(a,b)) return a;
  53.     if (upper(b,a)) return b;
  54.     for (int i=L;i>=0;--i) if (!upper(up[a][i],b)) a=up[a][i];
  55.     return up[a][0];
  56. }
  57.  
  58. inline int get(vector<tree> & t,int v,int sumadd=0){
  59.     return t[v].sum+(t[v].r-t[v].l+1)*(t[v].add+sumadd);
  60. }
  61.  
  62. void build(vector<tree> & t,int v,int l,int r){
  63.     t[v].l=l;t[v].r=r;t[v].add=t[v].sum=0;
  64.     if (l!=r){
  65.         build(t,v+v,l,(l+r)/2);
  66.         build(t,v+v+1,(l+r)/2+1,r);
  67.     }
  68. }
  69.  
  70. void inc(vector<tree> & t,int v,int l,int r){
  71.     if (t[v].l>r || t[v].r<l) return;
  72.     if (t[v].l>=l && t[v].r<=r) ++t[v].add;
  73.     else {
  74.         inc(t,v+v,l,r);
  75.         inc(t,v+v+1,l,r);
  76.         t[v].sum=get(t,v+v)+get(t,v+v+1);
  77.     }
  78. }
  79.  
  80. int get_sum(vector<tree> & t,int v,int l,int r,int sumadd=0){
  81.     if (t[v].l>r || t[v].r<l) return 0;
  82.     if (t[v].l>=l && t[v].r<=r) return get(t,v,sumadd);
  83.     return get_sum(t,v+v,l,r,sumadd+t[v].add)+get_sum(t,v+v+1,l,r,sumadd+t[v].add);
  84. }
  85.  
  86. inline void hldot(int v){
  87.     int k=0;
  88.     ways[++cw].pb(v);
  89.     where[v]=cw;
  90.     num[v]=k++;
  91.     for(;v!=1;){
  92.         int p=up[v][0];
  93.         if (f[v]<=f[p]/2) break;
  94.         ways[cw].pb(p);
  95.         where[p]=cw;
  96.         num[p]=k++;
  97.         v=p;
  98.     }
  99.     RSQ[cw].resize(4*k);
  100.     build(RSQ[cw],1,0,k-1);
  101. }
  102.  
  103. inline int get_count(int a,int b){
  104.     int lc=lca(a,b),v,ans=0;
  105.     if (lc==b) swap(a,b);
  106.     v=b;
  107.     for(;;){
  108.         if (where[v]!=where[lc]){
  109.             ans+=get_sum(RSQ[where[v]],1,num[v],ways[where[v]].size()-1);
  110.             v=up[ways[where[v]].back()][0];
  111.         } else {
  112.             ans+=get_sum(RSQ[where[v]],1,num[v],num[lc]-1);
  113.             break;
  114.         }
  115.     }
  116.     if (lc!=a){
  117.         swap(a,b);
  118.         v=b;
  119.         for(;;){
  120.             if (where[v]!=where[lc]){
  121.                 ans+=get_sum(RSQ[where[v]],1,num[v],ways[where[v]].size()-1);
  122.                 v=up[ways[where[v]].back()][0];
  123.             } else {
  124.                 ans+=get_sum(RSQ[where[v]],1,num[v],num[lc]-1);
  125.                 break;
  126.             }
  127.         }
  128.     }
  129.     return ans;
  130. }
  131.  
  132. inline void plaint(int a,int b) {
  133.     int lc=lca(a,b),v;
  134.     if (lc==b) swap(a,b);
  135.     v=b;
  136.     for (;;){
  137.         if (where[v]!=where[lc]){
  138.             inc(RSQ[where[v]],1,num[v],ways[where[v]].size()-1);
  139.             v=up[ways[where[v]].back()][0];
  140.         } else {
  141.             inc(RSQ[where[v]],1,num[v],num[lc]-1);
  142.             break;
  143.         }
  144.     }
  145.     if (lc!=a){
  146.         swap(a,b);
  147.         v=b;
  148.         for (;;){
  149.             if (where[v]!=where[lc]){
  150.                 inc(RSQ[where[v]],1,num[v],ways[where[v]].size()-1);
  151.                 v=up[ways[where[v]].back()][0];
  152.             } else {
  153.                 inc(RSQ[where[v]],1,num[v],num[lc]-1);
  154.                 break;
  155.             }
  156.         }
  157.     }
  158. }
  159.  
  160. int main(){
  161.     rwopen("grassplant");
  162.     scanf("%d%d\n",&n,&m);
  163.     forn(i,n-1){
  164.         int a,b;
  165.         scanf("%d%d\n",&a,&b);
  166.         add(a,b);
  167.     }
  168.     calc_up(1);
  169.     forn(i,n) if (i!=1 && !b[i]) hldot(i);
  170.     forn(i,m){
  171.         char c;int a,b;
  172.         scanf("%c %d %d\n",&c,&a,&b);
  173.         if (c=='P') plaint(a,b);
  174.         else printf("%d\n",get_count(a,b));
  175.     }
  176.     return 0;
  177. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement