【CF768G】The Winds of Winter 可持久化线段树 DFS序
来源:互联网 发布:淘宝客cms免费 编辑:程序博客网 时间:2024/06/05 06:19
题目大意
给定一棵
题解
首先用DFS序+可持久化线段树求出删掉这个点后剩下的联通块的大小的最大值
那么肯定是在最大的连通块上切下一块接到最小的连通块上。
假设切下的大小为
切下来的部分有三种可能:
1.在
2.在
3.在
时间复杂度:
代码
#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#include<ctime>#include<utility>#include<list>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int,int> pii;namespace sgt{ int rt1[100010]; int rt2[100010]; struct node { int lc,rc; int s; node() { lc=rc=s=0; } }; node a[10000010]; int cnt=0; int insert(int p1,int x,int l,int r) { int p=++cnt; a[p]=a[p1]; a[p].s++; if(l==r) return p; int mid=(l+r)>>1; if(x<=mid) a[p].lc=insert(a[p].lc,x,l,mid); else a[p].rc=insert(a[p].rc,x,mid+1,r); return p; } int suf(int p1,int p2,int p3,int p4,int x,int l,int r)//p1+p3-p2-p4 { int s=a[p1].s+a[p3].s-a[p4].s-a[p2].s; if(!s) return 0x3fffffff; if(l==r) return l; int mid=(l+r)>>1; int ls=a[a[p1].lc].s+a[a[p3].lc].s-a[a[p4].lc].s-a[a[p2].lc].s; if(x<=mid&&ls) { int lans=suf(a[p1].lc,a[p2].lc,a[p3].lc,a[p4].lc,x,l,mid); if(lans!=0x3fffffff) return lans; } return suf(a[p1].rc,a[p2].rc,a[p3].rc,a[p4].rc,x,mid+1,r); } int pre(int p1,int p2,int p3,int p4,int x,int l,int r) { int s=a[p1].s+a[p3].s-a[p4].s-a[p2].s; if(!s) return 0; if(l==r) return l; int mid=(l+r)>>1; int rs=a[a[p1].rc].s+a[a[p3].rc].s-a[a[p4].rc].s-a[a[p2].rc].s; if(x>mid&&rs) { int rans=pre(a[p1].rc,a[p2].rc,a[p3].rc,a[p4].rc,x,mid+1,r); if(rans) return rans; } return pre(a[p1].lc,a[p2].lc,a[p3].lc,a[p4].lc,x,l,mid); } int getmax(int p1,int p2,int p3,int p4,int l,int r) { int s=a[p1].s+a[p3].s-a[p4].s-a[p2].s; if(!s) return 0; if(l==r) return l; int mid=(l+r)>>1; int rs=a[a[p1].rc].s+a[a[p3].rc].s-a[a[p4].rc].s-a[a[p2].rc].s; if(rs) return getmax(a[p1].rc,a[p2].rc,a[p3].rc,a[p4].rc,mid+1,r); return getmax(a[p1].lc,a[p2].lc,a[p3].lc,a[p4].lc,l,mid); } int getmin(int p1,int p2,int p3,int p4,int l,int r) { int s=a[p1].s+a[p3].s-a[p4].s-a[p2].s; if(!s) return 0x3fffffff; if(l==r) return l; int mid=(l+r)>>1; int ls=a[a[p1].lc].s+a[a[p3].lc].s-a[a[p4].lc].s-a[a[p2].lc].s; if(ls) return getmin(a[p1].lc,a[p2].lc,a[p3].lc,a[p4].lc,l,mid); return getmin(a[p1].rc,a[p2].rc,a[p3].rc,a[p4].rc,mid+1,r); }}using sgt::rt1;using sgt::rt2;using sgt::insert;using sgt::suf;using sgt::pre;using sgt::getmax;using sgt::getmin;list<int> l[100010];int f[100010];int st[100010];int ed[100010];int s[100010];int w[100010];int ti;int n;void dfs1(int x){ st[x]=++ti; w[ti]=x; s[x]=1; for(auto v:l[x]) { dfs1(v); s[x]+=s[v]; } ed[x]=ti;}int update(int &a,int &b,int &c){ if(c>=a) { b=a; a=c; return 1; } else { b=max(b,c); return 2; } return 0;}int main(){ freopen("c.in","r",stdin); freopen("c.out","w",stdout); scanf("%d",&n); int rt,x,y; int i; for(i=1;i<=n;i++) { scanf("%d%d",&x,&y); if(x) { l[x].push_back(y); f[y]=x; } else rt=y; } dfs1(rt); for(i=1;i<=n;i++) { x=w[i]; rt2[x]=insert(rt2[f[x]],s[x],1,n); rt1[i]=insert(rt1[i-1],s[x],1,n); } for(i=1;i<=n;i++) { int mx=0,sec=0,mi=0x7fffffff; int s1,s2,s3,s4,ans; int mv; for(auto v:l[i]) { s1=s[v]; if(update(mx,sec,s1)==1) { s4=1; mv=v; } mi=min(mi,s1); } s1=n-s[i]; if(s1) { if(update(mx,sec,s1)==1) s4=2; mi=min(mi,s1); } ans=0x7fffffff; int mid=(mi+mx+1)>>1; int s5=mx-mid; if(i==1) int xxx=1; ans=min(ans,mx); if(s4==1) { s1=pre(rt1[ed[mv]],rt1[st[mv]-1],0,0,s5,1,n); s2=suf(rt1[ed[mv]],rt1[st[mv]-1],0,0,s5,1,n); ans=min(ans,max(sec,max(mi+s1,mx-s1))); ans=min(ans,max(sec,max(mi+s2,mx-s2))); } else if(s4==2) { s1=pre(rt2[f[i]],0,0,0,s5+s[i],1,n); s2=suf(rt2[f[i]],0,0,0,s5+s[i],1,n); if(s1) s1-=s[i]; if(s2!=0x3fffffff) s2-=s[i]; ans=min(ans,max(sec,max(mi+s1,mx-s1))); ans=min(ans,max(sec,max(mi+s2,mx-s2))); s1=pre(rt1[st[i]-1],rt1[ed[i]],rt1[n],rt2[f[i]],s5,1,n); s2=suf(rt1[st[i]-1],rt1[ed[i]],rt1[n],rt2[f[i]],s5,1,n); ans=min(ans,max(sec,max(mi+s1,mx-s1))); ans=min(ans,max(sec,max(mi+s2,mx-s2))); } printf("%d\n",ans); } return 0;}
阅读全文
0 0
- 【CF768G】The Winds of Winter 可持久化线段树 DFS序
- http://www.georgerrmartin.com/excerpt-from-the-winds-of-winter/
- codeforces768G The Winds of Winter -- 树上启发式合并
- 可持久化线段树&主席树、dfs序 Task Highways (aut)
- 【BZOJ3439】Kpm的MC密码 Trie+dfs序+可持久化线段树
- 【HDU 4348】To the moon【可持久化线段树】
- [HDOJ 4348] To the moon [线段树+可持久化]
- 【可持久化线段树】【hdu 4348】To the moon
- 【HDU】4348 To the moon 【可持久化线段树】
- Hdu-4348 To the moon(可持久化线段树)
- hdu4348:To the moon(可持久化线段树)
- 可持久化线段树
- 可持久化线段树
- 可持久化线段树
- 可持久化线段树
- 可持久化线段树
- 可持久化线段树
- 可持久化线段树
- 命令行退出和遇到的一些问题
- 基于双向链表的list
- offsetLeft与style.left的区别
- Python中的X[:,0]和X[:,1]
- Bitmap 图像解码以及缩略图生成----BitmapFactory类
- 【CF768G】The Winds of Winter 可持久化线段树 DFS序
- UVa10537 Toll! Revisited
- Java的JVM GC(Garbage Collection)垃圾回收原理机制及算法 .
- linux网络编程之socket(六):利用recv和readn函数实现readline函数
- 安卓代码简单实现电商购物车
- 解读 Redux 中间件的原理
- [未完待续]Clipboard提取或替换Windows系统剪贴板的文本内容
- App 后端架构设计方案 设计思想与最佳实践
- slf4j+logback实现日志存放到不同文件