标签:flip algo soft getc 连续 图片 cloc break names
一道很有奥妙的题.
发现修改操作和access有着不可不说的关系.
因为操作的特殊性,每种颜色在树上是一段连续的区间.不会被切开.
若x跟父亲颜色相同,设x到父亲的边的权值为0,否则为1
那么一个点到根的颜色就是它到跟路径上1的个数+1
修改从x到根,x到根的边全都变成0,x到跟路径上相邻的其他边都变成1
把1看成虚边,0看出实边,就相当于access操作
用lct维护即可得到每次需要修改的边,修改一条边相当于子树修改,线段树维护dfs序即可
newroot时候不需要单独处理,只需access的时候加减.注意access的时候加减的是rc/t那颗splay中深度最浅的节点,不是rc/t本身
查询修改都同遥远的国度,分类讨论.(注意修改也要讨论呀...你是改子树呀...)
然后观察了一下别人的代码,发现找我包含根的那个儿子不应该暴力枚举我的儿子而应该预处理倍增数组从根跳,,改了一下..虽然数据也不卡我...
1 //Achen 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdlib> 6 #include<vector> 7 #include<cstdio> 8 #include<queue> 9 #include<cmath> 10 #include<set> 11 #include<map> 12 #define For(i,a,b) for(int i=(a);i<=(b);i++) 13 #define Rep(i,a,b) for(int i=(a);i>=(b);i--) 14 const int N=3e5+7; 15 typedef long long LL; 16 typedef double db; 17 using namespace std; 18 int n,m,rt; 19 char o[15]; 20 21 template<typename T> void read(T &x) { 22 char ch=getchar(); x=0; T f=1; 23 while(ch!=‘-‘&&(ch<‘0‘||ch>‘9‘)) ch=getchar(); 24 if(ch==‘-‘) f=-1,ch=getchar(); 25 for(;ch>=‘0‘&&ch<=‘9‘;ch=getchar()) x=x*10+ch-‘0‘; x*=f; 26 } 27 28 int ecnt,fir[N],nxt[N<<1],to[N<<1]; 29 void add(int u,int v) { 30 nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; 31 nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; 32 } 33 34 LL sg[N<<2],lz[N<<2]; 35 #define ls x<<1 36 #define rs ((x<<1)|1) 37 #define mid ((l+r)>>1) 38 void down(int x,int l_len,int r_len) { 39 if(!lz[x]) return; 40 if(l_len) sg[ls]=sg[ls]+l_len*lz[x],lz[ls]=lz[ls]+lz[x]; 41 if(r_len) sg[rs]=sg[rs]+r_len*lz[x],lz[rs]=lz[rs]+lz[x]; 42 lz[x]=0; 43 } 44 45 void update(int x,int l,int r,int ql,int qr,int v) { 46 if(ql>qr) return; 47 if(l>=ql&&r<=qr) { 48 sg[x]=sg[x]+(LL)(r-l+1)*v; 49 lz[x]=lz[x]+v; return; 50 } 51 down(x,mid-l+1,r-mid); 52 if(ql<=mid) update(ls,l,mid,ql,qr,v); 53 if(qr>mid) update(rs,mid+1,r,ql,qr,v); 54 sg[x]=sg[ls]+sg[rs]; 55 } 56 57 LL qry(int x,int l,int r,int ql,int qr) { 58 if(ql>qr) return 0; 59 if(l>=ql&&r<=qr) return sg[x]; 60 down(x,mid-l+1,r-mid); 61 if(qr<=mid) return qry(ls,l,mid,ql,qr); 62 if(ql>mid) return qry(rs,mid+1,r,ql,qr); 63 return qry(ls,l,mid,ql,qr)+qry(rs,mid+1,r,ql,qr); 64 } 65 66 int p[N],ch[N][2],flip[N],st[N][20]; 67 68 int sz[N],fa[N],dfn[N],R[N],dfs_clock; 69 void dfs(int x,int FA) { 70 sz[x]=1; 71 p[x]=FA; 72 fa[x]=FA; 73 st[x][0]=FA; 74 For(i,1,19) st[x][i]=st[st[x][i-1]][i-1]; 75 R[x]=R[FA]+1; 76 dfn[x]=++dfs_clock; 77 update(1,1,n,dfn[x],dfn[x],R[x]); 78 for(int i=fir[x];i;i=nxt[i]) if(to[i]!=FA) { 79 dfs(to[i],x); 80 sz[x]+=sz[to[i]]; 81 } 82 } 83 84 #define lc ch[x][0] 85 #define rc ch[x][1] 86 87 void down(int x) { 88 if(!flip[x]) return; 89 swap(lc,rc); 90 flip[lc]^=1; 91 flip[rc]^=1; 92 flip[x]^=1; 93 } 94 95 int isroot(int x) { return ch[p[x]][0]!=x&&ch[p[x]][1]!=x; } 96 97 void rotate(int x) { 98 int y=p[x],z=p[y],l=(x==ch[y][1]),r=l^1; 99 if(!isroot(y)) ch[z][y==ch[z][1]]=x; p[x]=z; 100 ch[y][l]=ch[x][r]; p[ch[x][r]]=y; 101 ch[x][r]=y; p[y]=x; 102 } 103 104 void splay(int x) { 105 static int g[N],top=0,tp; 106 for(tp=x;!isroot(tp);tp=p[tp]) g[++top]=tp; 107 g[++top]=tp; 108 while(top) down(g[top--]); 109 for(;!isroot(x);rotate(x)) { 110 int y=p[x],z=p[y]; 111 if(!isroot(y)) ((x==ch[y][1])^(y==ch[z][1]))?rotate(x):rotate(y); 112 } 113 } 114 115 void change(int x,int v) { 116 if(x==rt) update(1,1,n,1,n,v); 117 else if(dfn[rt]>dfn[x]&&dfn[rt]<dfn[x]+sz[x]) { 118 int y=rt; 119 Rep(i,19,0) if(R[st[y][i]]>R[x]) y=st[y][i]; 120 /*for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa[x]) { 121 y=to[i]; 122 if(dfn[rt]>=dfn[y]&&dfn[rt]<dfn[y]+sz[y]) break; 123 } */ 124 update(1,1,n,1,dfn[y]-1,v); 125 update(1,1,n,dfn[y]+sz[y],n,v); 126 } 127 else update(1,1,n,dfn[x],dfn[x]+sz[x]-1,v); 128 } 129 130 void access(int x) { 131 for(int t=0;x;x=p[t=x]) { 132 splay(x); 133 if(rc) { 134 int tp=rc; down(tp); while(ch[tp][0]) { tp=ch[tp][0]; down(tp); } 135 change(tp,1); //shi bian xu 136 } 137 if(t) { 138 int tp=t; down(tp); while(ch[tp][0]) { tp=ch[tp][0]; down(tp); } 139 change(tp,-1); // xu bian shi 140 } 141 rc=t; 142 } 143 } 144 145 void newroot(int x) { 146 access(x); 147 splay(x); 148 flip[x]^=1; 149 rt=x; 150 } 151 152 void solve(int x) { 153 db ans=0.0; 154 if(x==rt) ans=(db)sg[1]/(1.0*n); 155 else if(dfn[rt]>dfn[x]&&dfn[rt]<dfn[x]+sz[x]) { 156 /*int y=0; 157 for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa[x]) { 158 y=to[i]; 159 if(dfn[rt]>=dfn[y]&&dfn[rt]<dfn[y]+sz[y]) break; 160 }*/ 161 int y=rt; 162 Rep(i,19,0) if(R[st[y][i]]>R[x]) y=st[y][i]; 163 ans=((db)qry(1,1,n,1,dfn[y]-1)+qry(1,1,n,dfn[y]+sz[y],n))/(1.0*(n-sz[y])); 164 } 165 else ans=(db)qry(1,1,n,dfn[x],dfn[x]+sz[x]-1)/(1.0*sz[x]); 166 printf("%.10lf\n",ans); 167 } 168 169 //#define DEBUG 170 int main() { 171 #ifdef DEBUG 172 freopen("3779.in","r",stdin); 173 freopen("3779.out","w",stdout); 174 #endif 175 read(n); read(m); rt=1; 176 For(i,2,n) { 177 int x,y; 178 read(x); read(y); 179 add(x,y); 180 } 181 dfs(rt,0); 182 For(ti,1,m) { 183 int x; 184 scanf("%s",o); read(x); 185 if(o[2]==‘L‘) access(x); 186 else if(o[2]==‘C‘) newroot(x); 187 else if(o[2]==‘Q‘) solve(x); 188 } 189 return 0; 190 }
标签:flip algo soft getc 连续 图片 cloc break names
原文地址:https://www.cnblogs.com/Achenchen/p/8982689.html