首页 > 代码库 > BZOJ 3731 Gty的超级妹子树 块状树
BZOJ 3731 Gty的超级妹子树 块状树
题目大意:同3720 增加了一个操作 即删除一个点与父亲节点的连边
3720题解见 http://blog.csdn.net/popoqqq/article/details/41481439
断开一个节点与父节点的连边时
如果这个点是所在块的根节点,直接断掉就行
如果这个点不是所在块的根节点,那么就要把这个块分裂,这个点以及在块中的子树都分裂到新的块中,细节讨论较多不大好写0.0
然后是一些小问题
1.此题卡内存 静态不用想了 开vector吧
2.是我常数写渣了还是这题真的卡时间0.0 之前是把块先清空然后再往里加 T到死…… 没办法了改成分裂出的点从原块中删除 然后再加进新的块中 然后加了一堆优化QAQ
#include <cmath> #include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 100100 #define Block_Size 200200 using namespace std; namespace IOStream{ const int L=1<<15; char buffer[L]; char *S,*T; char Get_Char() { if(S==T) { T=(S=buffer)+fread(buffer,1,L,stdin); if(S==T) return EOF; } return *S++; } int Get_Int() { int re=0; char c; do c=Get_Char(); while(c<'0'||c>'9'); while(c>='0'&&c<='9') re=(re<<1)+(re<<3)+(c-'0'),c=Get_Char(); return re; } } struct Block{ vector<int>a; void Insert(int x) { a.insert( lower_bound(a.begin(),a.end(),x+1) , x ); } void Delete(int x) { a.erase( lower_bound(a.begin(),a.end(),x) ); } void Modify(int x,int y) { Delete(x); Insert(y); } int Query(int x) { int temp=upper_bound(a.begin(),a.end(),x)-a.begin()+1; return a.size()-temp+1; } }blocks[Block_Size]; struct abcd{ int to,next; bool ban; }table[M*3]; int head[M<<1],block_head[Block_Size],tot; int n,m,block,ans,cnt; int a[M<<1],fa[M<<1],belong[M<<1],into[M],block_into[Block_Size]; void Add(int _head[],int x,int y) { table[++tot].to=y; table[tot].next=_head[x]; _head[x]=tot; if(_head==head) into[y]=tot; else block_into[y]=tot; } void DFS(int x) { int i; if(!fa[x]||blocks[belong[fa[x]]].a.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]) { table[i].ban=1; continue; } 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) if(!table[i].ban) 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].ban) if(belong[table[i].to]==belong[x]) DFS(table[i].to,y); else Block_DFS(belong[table[i].to],y); } void DFS2(int x) { int i; for(i=head[x];i;i=table[i].next) if(!table[i].ban) into[table[i].to]=i,DFS2(table[i].to); } void Decomposition(int x,bool flag,int neo,int z,int ori) { int i; if(x==z) flag=1; //blocks[belong[x]=(flag?neo:ori)].Insert(a[x]); if(flag) { blocks[ori].Delete(a[x]); blocks[belong[x]=neo].Insert(a[x]); } for(i=head[x];i;i=table[i].next) if(!table[i].ban) { if(belong[table[i].to]==ori) Decomposition(table[i].to,flag,neo,z,ori); else if(flag) table[block_into[belong[table[i].to]]].ban=1,Add(block_head,neo,belong[table[i].to]); } } int main() { //#ifdef C_PoPoQQQ //freopen("data.in","r",stdin); //freopen("data.out","w",stdout); //#endif int i,j,x,y,p; cin>>n; for(i=1;i<n;i++) Add(head,x=IOStream::Get_Int(),y=IOStream::Get_Int() ),Add(head,y,x); for(i=1;i<=n;i++) a[i]=IOStream::Get_Int(); block=static_cast<int>(sqrt(n*log2(n))+1e-7); DFS(1); DFS2(1); m=IOStream::Get_Int(); for(i=1;i<=m;i++) { #ifdef C_PoPoQQQ //ans=0; #endif p=IOStream::Get_Int(); switch(p) { case 0: x=IOStream::Get_Int()^ans,y=IOStream::Get_Int()^ans; ans=0; DFS(x,y); printf("%d\n",ans); break; case 1: x=IOStream::Get_Int()^ans,y=IOStream::Get_Int()^ans; blocks[belong[x]].Modify(a[x],y); a[x]=y; break; case 2: x=IOStream::Get_Int()^ans,y=IOStream::Get_Int()^ans; a[++n]=y; Add(head,x,n); fa[n]=x; if(blocks[belong[x]].a.size()==block) blocks[belong[n]=++cnt].Insert(y),Add(block_head,belong[x],cnt); else blocks[belong[n]=belong[x]].Insert(y); break; case 3: x=IOStream::Get_Int()^ans; if(belong[fa[x]]!=belong[x]) table[block_into[belong[x]]].ban=1; else { for(y=x;fa[y]&&belong[fa[y]]==belong[x];y=fa[y]); //blocks[belong[x]].a.clear(); Decomposition(y,0,++cnt,x,belong[x]); } table[into[x]].ban=1; fa[x]=0; break; } } return 0; }
BZOJ 3731 Gty的超级妹子树 块状树
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。