【块状树】bzoj3720 Gty的妹子树

块状树。
教程见:http://z55250825.blog.163.com/blog/static/1502308092014163413858/
将树按一定大小分块,分成许多子树,在每个子树的根节点记录一个数组,存储这个块中数据的有序表,查询时二分即可。

对于添加节点操作,若添加的节点的父节点所在块大小没有超过size,则添加到上面的块里,否则另起一块。

这个size值要注意,由于有二分操作,所以大小定为sqrt(n*log2(n))比较好,而不是sqrt(n),证明略。

时间复杂度O(n*sqrt(n)*log(sqrt(n)))。

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cmath>
  4 #include<vector>
  5 using namespace std;
  6 #define maxn 60001
  7 typedef vector<int>::iterator ITER;
  8 vector<int>List[maxn],Goto[maxn];
  9 int res,CH[20],Num;char c;
 10 inline int Ge()
 11 {
 12     res=0;c='*';
 13     while(c<'0'||c>'9')c=getchar();
 14     while(c>='0'&&c<='9'){res=res*10+(c-'0');c=getchar();}
 15     return res;
 16 }
 17 inline void P(int x)
 18 {
 19     if(!x){putchar('0');puts("");return;}Num=0;
 20     while(x>0){CH[++Num]=x%10;x/=10;}
 21     while(Num)putchar(CH[Num--]+48);
 22     putchar('\n');
 23 }
 24 struct Graph
 25 {
 26     int v[maxn<<1],first[maxn<<1],next[maxn<<1],en;
 27     void AddEdge(const int &a,const int &b)
 28     {v[++en]=b;next[en]=first[a];first[a]=en;}
 29 };
 30 Graph G,son;
 31 int top[maxn],siz[maxn],sz,w[maxn];
 32 bool vis[maxn];
 33 int n,x,y,m,op;
 34 int ans,val,U;
 35 void makeblock(int cur)
 36 {
 37     vis[cur]=true;
 38     for(int i=G.first[cur];i;i=G.next[i])
 39       if(!vis[G.v[i]])
 40         {
 41           son.AddEdge(cur,G.v[i]);
 42           if(siz[top[cur]]<sz)
 43             {
 44               List[top[cur]].push_back(w[G.v[i]]);
 45               siz[top[cur]]++;
 46               top[G.v[i]]=top[cur];
 47             }
 48           makeblock(G.v[i]);
 49         }
 50 }
 51 void makeGoto(int cur)
 52 {
 53     for(int i=son.first[cur];i;i=son.next[i])
 54       {
 55           if(top[son.v[i]]!=top[cur])
 56           Goto[top[cur]].push_back(son.v[i]);
 57         makeGoto(son.v[i]);
 58       }
 59 }
 60 void dfs(int cur)
 61 {
 62     ans+=( List[cur].end() - upper_bound( List[cur].begin() , List[cur].end() , val ) );
 63     for(ITER it=Goto[cur].begin();it!=Goto[cur].end();it++)
 64       dfs(*it);
 65 }
 66 void dfs_block(int cur)
 67 {
 68     if(w[cur]>val) ans++;
 69     for(int i=son.first[cur];i;i=son.next[i])
 70       if(top[son.v[i]]==top[cur]) dfs_block(son.v[i]);
 71       else dfs(son.v[i]);
 72 }
 73 void query()
 74 {
 75     ans=0;
 76     if(U==top[U]) dfs(U);
 77     else dfs_block(U);
 78     P(ans);
 79 }
 80 void update()
 81 {
 82     List[top[U]].erase( lower_bound(List[top[U]].begin(),List[top[U]].end(),w[U]) );
 83     w[U]=val;
 84     List[top[U]].insert( lower_bound(List[top[U]].begin(),List[top[U]].end(),val+1) , val );
 85 }
 86 void AddPoint()
 87 {
 88     n++;
 89     if(siz[top[U]]<sz)
 90       {
 91           top[n]=top[U];
 92           siz[top[n]]++;
 93       }
 94     else
 95       {
 96           top[n]=n;
 97           siz[n]++;
 98           Goto[top[U]].push_back(n);
 99       }
100     son.AddEdge(U,n);
101     w[n]=val;
102     List[top[n]].insert( lower_bound(List[top[n]].begin(),List[top[n]].end(),val+1) , val );
103 }
104 int main()
105 {
106     n=Ge();
107     for(int i=1;i<n;i++)
108       {
109           x=Ge();y=Ge();
110           G.AddEdge(x,y);
111           G.AddEdge(y,x);
112       }
113     sz=sqrt((double)n*log2(n));
114     for(int i=1;i<=n;i++)
115       {
116           w[i]=Ge();
117           top[i]=i;
118           siz[i]=1;
119       }
120     makeblock(1);
121     for(int i=1;i<=n;i++)
122       if(top[i]==i)
123         {
124           List[i].push_back(w[i]);
125           sort(List[i].begin(),List[i].end());
126         }
127     makeGoto(1);
128     m=Ge();
129     for(int i=1;i<=m;i++)
130       {
131           op=Ge();U=Ge();val=Ge();U^=ans;val^=ans;
132           if(!op)query();
133           else if(op==1)update();
134           else AddPoint();
135       }
136     return 0;
137 }

 

posted @ 2014-09-21 07:54  AutSky_JadeK  阅读(682)  评论(4编辑  收藏  举报
TVアニメ「Charlotte(シャーロット)」公式サイト TVアニメ「Charlotte(シャーロット)」公式サイト