【块状树】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 }
——The Solution By AutSky_JadeK From UESTC
转载请注明出处:http://www.cnblogs.com/autsky-jadek/