首页 > [BZOJ3779]重组病毒(LCT+DFS序线段树)

[BZOJ3779]重组病毒(LCT+DFS序线段树)

同[BZOJ4817]树点涂色,只是多了换根操作,分类讨论下即可。

  1 #include
  2 #include
  3 #define lc ch[x][0]
  4 #define rc ch[x][1]
  5 #define ls (x<<1)
  6 #define rs (ls|1)
  7 #define lson ls,L,mid
  8 #define rson rs,mid+1,R
  9 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 10 #define For(i,x) for (int i=h[x],k; i; i=nxt[i])
 11 typedef long long ll;
 12 using namespace std;
 13 
 14 const int N=100010;
 15 char op[10];
 16 ll tag[N<<2],sm[N<<2];
 17 int n,m,u,v,x,rt,cnt,tim,rev[N],h[N],nxt[N<<1],to[N<<1];
 18 int L[N],R[N],dep[N],fa[N][20],ch[N][2],sz[N],f[N];
 19 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
 20 
 21 inline int rd(){
 22     int x=0; char ch=getchar(); bool f=0;
 23     while (ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
 24     while (ch>='0' && ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
 25     return f ? -x : x;
 26 }
 27 
 28 int jump(int x,int k){
 29     for (int i=18; ~i; i--) if (k&(1<return x;
 30 }
 31 
 32 void push(int x,int L,int R){
 33     if (!tag[x]) return;
 34     int mid=(L+R)>>1;
 35     sm[ls]+=tag[x]*(mid-L+1); tag[ls]+=tag[x];
 36     sm[rs]+=tag[x]*(R-mid); tag[rs]+=tag[x];
 37     tag[x]=0;
 38 }
 39 
 40 void mdf(int x,int L,int R,int l,int r,int k){
 41     if (L==l && r==R){ sm[x]+=1ll*k*(R-L+1); tag[x]+=k; return; }
 42     int mid=(L+R)>>1; push(x,L,R);
 43     if (r<=mid) mdf(lson,l,r,k);
 44     else if (l>mid) mdf(rson,l,r,k);
 45         else mdf(lson,l,mid,k),mdf(rson,mid+1,r,k);
 46     sm[x]=sm[ls]+sm[rs];
 47 }
 48 
 49 ll que(int x,int L,int R,int l,int r){
 50     if (L==l && r==R) return sm[x];
 51     int mid=(L+R)>>1; push(x,L,R);
 52     if (r<=mid) return que(lson,l,r);
 53     else if (l>mid) return que(rson,l,r);
 54         else return que(lson,l,mid)+que(rson,mid+1,r);
 55 }
 56 
 57 void dfs(int x){
 58     L[x]=++tim; dep[x]=dep[fa[x][0]]+1; sz[x]=1;
 59     rep(i,1,18) fa[x][i]=fa[fa[x][i-1]][i-1];
 60     mdf(1,1,n,L[x],L[x],dep[x]);
 61     For(i,x) if ((k=to[i])!=fa[x][0]) fa[k][0]=x,f[k]=x,dfs(k),sz[x]+=sz[k];
 62     R[x]=tim;
 63 }
 64 
 65 bool isrt(int x){ return (!f[x]) || (ch[f[x]][0]!=x && ch[f[x]][1]!=x); }
 66 void put(int x){ swap(lc,rc); rev[x]^=1; }
 67 void push(int x){ if (rev[x]) put(lc),put(rc),rev[x]=0; }
 68 void pd(int x){ if (!isrt(x)) pd(f[x]); push(x); }
 69 
 70 void rot(int x){
 71     int y=f[x],z=f[y],w=ch[y][1]==x;
 72     if (!isrt(y)) ch[z][ch[z][1]==y]=x;
 73     f[x]=z; f[y]=x; f[ch[x][w^1]]=y;
 74     ch[y][w]=ch[x][w^1]; ch[x][w^1]=y;
 75 }
 76 
 77 void splay(int x){
 78     pd(x);
 79     while (!isrt(x)){
 80         int y=f[x],z=f[y];
 81         if (!isrt(y)) (ch[z][1]==y)^(ch[y][1]==x) ? rot(x) : rot(y);
 82         rot(x);
 83     }
 84 }
 85 
 86 void work(int x,int k){
 87     if (rt==x) mdf(1,1,n,1,n,k);
 88     else if (L[rt]>=L[x] && L[rt]<=R[x]){
 89         int t=jump(rt,dep[rt]-dep[x]-1);
 90         if (L[t]>1) mdf(1,1,n,1,L[t]-1,k);
 91         if (R[t]1,1,n,R[t]+1,n,k);
 92     }else mdf(1,1,n,L[x],R[x],k);
 93 }
 94 
 95 int find(int x){
 96     push(x);
 97     while (lc) x=lc,push(x);
 98     return x;
 99 }
100 
101 void access(int x){
102     for (int y=0; x; y=x,x=f[x]){
103         splay(x);
104         if (rc) work(find(rc),1);
105         if (y) work(find(y),-1);
106         rc=y;
107     }
108 }
109 
110 void mkrt(int x){ access(x); splay(x); put(x); }
111 
112 int main(){
113     freopen("bzoj3779.in","r",stdin);
114     freopen("bzoj3779.out","w",stdout);
115     n=rd(); m=rd();
116     rep(i,2,n) u=rd(),v=rd(),add(u,v),add(v,u);
117     dfs(1); rt=1;
118     while (m--){
119         scanf("%s",op); x=rd();
120         if (op[2]=='L') access(x);
121         if (op[2]=='C') mkrt(x),rt=x;
122         if (op[2]=='Q'){
123             if (rt==x) printf("%.10lf
",1.*que(1,1,n,1,n)/n);
124             else if (L[rt]>=L[x] && L[rt]<=R[x]){
125                 int t=jump(rt,dep[rt]-dep[x]-1);
126                 ll res1=L[t]>1 ? que(1,1,n,1,L[t]-1) : 0;
127                 ll res2=R[t]1,1,n,R[t]+1,n) : 0;
128                 printf("%.10lf
",1.*(res1+res2)/(n-sz[t]));
129             }else printf("%.10lf
",1.*que(1,1,n,L[x],R[x])/sz[x]);
130         }
131     }
132     return 0;
133 }

 

转载于:https://www.cnblogs.com/HocRiser/p/10300424.html

更多相关:

  •         Apache POI是一个开源的利用Java读写Excel,WORD等微软OLE2组件文档的项目。        我的需求是对Excel的数据进行导入或将数据以Excel的形式导出。先上简单的测试代码:package com.xing.studyTest.poi;import java.io.FileInputSt...

  • 要取得[a,b)的随机整数,使用(rand() % (b-a))+ a; 要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a; 要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1; 通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。 要取得a到b之间的...

  • 利用本征图像分解(Intrinsic Image Decomposition)算法,将图像分解为shading(illumination) image 和 reflectance(albedo) image,计算图像的reflectance image。 Reflectance Image 是指在变化的光照条件下能够维持不变的图像部分...

  • 题目:面试题39. 数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 输出: 2 限制: 1 <= 数组长度 <= 50000 解题: cl...

  • 题目:二叉搜索树的后序遍历序列 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。 参考以下这颗二叉搜索树:      5     /    2   6   /  1   3示例 1: 输入: [1,6,3,2,5] 输出...

  • #include #include #include #include #include #include #include

  • 题目:表示数值的字符串 请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100"、"5e2"、"-123"、"3.1416"、"0123"及"-1E-16"都表示数值,但"12e"、"1a3.14"、"1.2.3"、"+-5"及"12e+5.4"都不是。 解题: 数值错误的形式有多种多样,但是正确的...

  • 加法伺候  //超过20位数值相加---------------------------------------- function bigNumAdd(a, b) {if (!(typeof a === "string" && typeof b === "string")) return console.log("传入参数必...

  • 业务场景: 从中文字句中匹配出指定的中文子字符串 .这样的情况我在工作中遇到非常多, 特梳理总结如下. 难点: 处理GBK和utf8之类的字符编码, 同时正则匹配Pattern中包含汉字,要汉字正常发挥作用,必须非常谨慎.推荐最好统一为utf8编码,如果不是这种最优情况,也有酌情处理. 往往一个具有普适性的正则表达式会简化程...

  • 简单record 一下 #include // 'struct sockaddr_in' #include #include // 'struct ifreq' and 'struct if_nameindex' #include #inc...

  • $dp$。 这道题最关键的是这句话: 跳出思维局限大胆设状态,设$f_{x, i, j}$表示从$x$到根要经过$i$条公路,$j$条铁路的代价,那么对于一个叶子结点,有$f_{x, i, j} = c_x * (a_x + i) * (b_x + j)$,对于内部结点,有转移:   $f_{x, i, j} = min(f_{lso...

  • 合作者:201631062327,201631062128码云地址:https://gitee.com/LIUJIA6/WordCount3 一:项目说明 本次项目是在上次作业WorldCount的基础上,利用结对编程的思想,完成对WorldCount项目的功能扩展 -s 递归处理目录下符合条件的文件。(实现)-a 返回更复杂的数据(...

  • Description 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示。例如可以将魔咒字符 1、2 拼凑起来形成一个魔咒串 [1,2]。 一个魔咒串 S 的非空字串被称为魔咒串 S 的生成魔咒。 例如 S=[1,2,1] 时,它的生成魔咒有 [1]、[2]、[1,2]、[2,1]、[1,2,1] 五种。S=[1,1,1] 时,它的生...

  •   【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=5972   【题目大意】   给出一个字符串,找出其中所有的符合特定模式的子串位置,符合特定模式是指,该子串的长度为n,并且第i个字符需要在给定的字符集合Si中    【题解】   利用ShiftAnd匹配算法。   bt[i]表示...

  • 首先我们可以发现如果错过了一个加油站,而继续往前走的时候没有油了,可以再假装之前经过加油站的时候加过油 于是我们维护一个大根堆,表示错过的加油站是哪些,每当没有油的时候从堆顶取出最大值加上去即可   1 /**************************************************************...