博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[BJOI2014] 大融合
阅读量:4449 次
发布时间:2019-06-07

本文共 2596 字,大约阅读时间需要 8 分钟。

一道不怎么裸的LCT。

这道题明显是询问一条边所连接的两个连通块的大小之积。

LCT怎么维护子树大小呢?

推荐一个大佬的博客():大佬的这篇博客有详解也有题,真心很棒的。

回到LCT,维护子树信息的话,我的理解就是把虚子树的信息也记录下来。

更新子树信息的时候把虚子树的也加进去。

至于怎么维护虚子树信息:

access和link的时候改变了树的形态,所以要顺便更新一下虚子树的信息。

access的时候是失去一个虚儿子又得到一个虚儿子。

link的时候连完边就顺手更新了。

别的操作没改变树的形态,所以虚子树信息不会变,代码跟原来一模一样的。

所以这道题现在就基本上也是裸题啦。

1 #include
2 #include
3 #include
4 #define id(x) (s[f[x]][1]==x) 5 using namespace std; 6 7 int n,m; 8 int s[100005][2],f[100005],szi[100005],sz[100005]; 9 bool rt[100005],rev[100005]; 10 11 void pushup(int p) 12 { 13 sz[p]=sz[s[p][0]]+sz[s[p][1]]+szi[p]+1; 14 } 15 16 void reverse(int p) 17 { 18 swap(s[p][0],s[p][1]); 19 rev[p]^=1; 20 } 21 22 void pushdown(int p) 23 { 24 if(!rev[p])return; 25 reverse(s[p][0]); 26 reverse(s[p][1]); 27 rev[p]=0; 28 } 29 30 void down(int p) 31 { 32 if(!rt[p])down(f[p]); 33 pushdown(p); 34 } 35 36 void rotate(int p) 37 { 38 int k=id(p); 39 int fa=f[p]; 40 if(rt[fa])rt[p]=1,rt[fa]=0; 41 else s[f[fa]][id(fa)]=p; 42 s[fa][k]=s[p][!k]; 43 s[p][!k]=fa; 44 f[p]=f[fa]; 45 f[fa]=p; 46 f[s[fa][k]]=fa; 47 pushup(fa); 48 pushup(p); 49 } 50 51 void splay(int p) 52 { 53 down(p); 54 while(!rt[p]) 55 { 56 int fa=f[p]; 57 if(rt[fa]) 58 { 59 rotate(p); 60 return; 61 } 62 if(id(p)^id(fa))rotate(p); 63 else rotate(fa); 64 rotate(p); 65 } 66 } 67 68 void access(int p) 69 { 70 int son=0; 71 while(p) 72 { 73 splay(p); 74 szi[p]+=sz[s[p][1]]; 75 rt[s[p][1]]=1,rt[son]=0; 76 s[p][1]=son; 77 szi[p]-=sz[s[p][1]]; 78 pushup(p); 79 son=p,p=f[p]; 80 } 81 } 82 83 void mtr(int p) 84 { 85 access(p); 86 splay(p); 87 reverse(p); 88 } 89 90 void isolate(int x,int y) 91 { 92 mtr(x); 93 access(y); 94 splay(y); 95 } 96 97 int main() 98 { 99 scanf("%d%d",&n,&m);100 for(int i=1;i<=n;i++)sz[i]=rt[i]=1;101 for(int i=1;i<=m;i++)102 {103 char op[5];104 scanf("%s",op+1);105 int x,y;106 scanf("%d%d",&x,&y);107 if(op[1]=='A')108 {109 isolate(x,y);110 f[x]=y;111 szi[y]+=sz[x];112 pushup(y);113 }114 if(op[1]=='Q')115 {116 isolate(x,y);117 printf("%lld\n",(long long)(szi[x]+1)*(szi[y]+1));118 }119 }120 return 0;121 }

 

转载于:https://www.cnblogs.com/eternhope/p/9671355.html

你可能感兴趣的文章
windows安装weblogic和域的建立
查看>>
Redis详解入门篇(转载)
查看>>
git(二)
查看>>
JS常用方法
查看>>
Knockout.js 数据验证之插件版和无插件版
查看>>
git--windwos下的安装与使用(一)
查看>>
[倍增][最短路-Floyd][dp]
查看>>
OCP换题库了,最新052考试题库及答案整理-3
查看>>
SpringAOP用到了什么代理,以及动态代理与静态代理的区别
查看>>
利用STM32CubeMX来生成USB_HID_Mouse工程【添加ADC】(1)
查看>>
【leetcode】Populating Next Right Pointers in Each Node
查看>>
luogu p1417 烹调方案
查看>>
实例源码--Android理财工具源码
查看>>
service name和SID的区别
查看>>
Configuration File (php.ini) Path Loaded Configuration File 都有加载php.ini文件,有什么不同的地方?...
查看>>
15 分钟学会使用 Git 和远程代码库
查看>>
BZOJ 1754: [Usaco2005 qua]Bull Math
查看>>
ADV-时间分配
查看>>
Json.net日期格式化设置
查看>>
input输入框自动填充黄色背景解决方案
查看>>