题目大意:维护一棵树,每个点有一个权值,提供下列操作:
1.询问某棵子树中有多少个节点的权值大于x
2.修改某个节点的权值
3.增加一个叶子节点
强制在线
传说中的树分块
首先DFS,对于每个节点,如果这个节点的父亲节点所在块未满,就塞进父节点所在块中,否则自成一块,然后与父节点所在的块连边
添加节点同理
然后就按照分块直接搞吧0.0 细节实在是太多了 所以写挂的地方看看本蒟蒻的代码就好了0.0
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 30300 using namespace std; struct Block{ int a[210],size; void Insert(int x) { int i; ++size; for(i=size;i>1&&a[i-1]>x;i--) a[i]=a[i-1]; a[i]=x; } void Modify(int x,int y) { int temp=lower_bound(a+1,a+size+1,x)-a; for(;temp<size&&a[temp+1]<y;temp++) a[temp]=a[temp+1]; for(;temp>1&&a[temp-1]>y;temp--) a[temp]=a[temp-1]; a[temp]=y; } int Query(int x) { int temp=upper_bound(a+1,a+size+1,x)-a; return size-temp+1; } }blocks[10100]; struct abcd{ int to,next; }table[M<<2]; int head[M<<1],block_head[M],tot; int n,m,block,ans,cnt; int a[M<<1],fa[M<<1],belong[M<<1]; void Add(int _head[],int x,int y) { table[++tot].to=y; table[tot].next=_head[x]; _head[x]=tot; } void DFS(int x) { int i; if(blocks[belong[fa[x]]].size==block) blocks[belong[x]=++cnt].Insert(a[x]),Add(block_head,belong[fa[x]],cnt); else blocks[belong[x]=belong[fa[x]]].Insert(a[x]); for(i=head[x];i;i=table[i].next) if(table[i].to!=fa[x]) fa[table[i].to]=x,DFS(table[i].to); } void Block_DFS(int x,int y) { int i; ans+=blocks[x].Query(y); for(i=block_head[x];i;i=table[i].next) Block_DFS(table[i].to,y); } void DFS(int x,int y) { int i; if(a[x]>y) ++ans; for(i=head[x];i;i=table[i].next) if(table[i].to!=fa[x]) if(belong[table[i].to]==belong[x]) DFS(table[i].to,y); else Block_DFS(belong[table[i].to],y); } int main() { int i,j,x,y,p; cin>>n; for(i=1;i<n;i++) scanf("%d%d",&x,&y),Add(head,x,y),Add(head,y,x); for(i=1;i<=n;i++) scanf("%d",&a[i]); block=static_cast<int>(sqrt(n)+1e-7); DFS(1); cin>>m; for(i=1;i<=m;i++) { scanf("%d%d%d",&p,&x,&y); x^=ans;y^=ans; switch(p) { case 0: ans=0; DFS(x,y); printf("%d\n",ans); break; case 1: blocks[belong[x]].Modify(a[x],y); a[x]=y; break; case 2: a[++n]=y; Add(head,x,n); fa[n]=x; if(blocks[belong[x]].size==block) blocks[belong[n]=++cnt].Insert(y),Add(block_head,belong[x],cnt); else blocks[belong[n]=belong[x]].Insert(y); break; } } return 0; }
原文地址:http://blog.csdn.net/popoqqq/article/details/41481439