洛谷P2147 SDOI2008 洞穴勘测 (LCT)

大模板

复制代码
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int N=1e4+5;
  4 int n,m,a[N],w[N];
  5 struct node{
  6     int fa,lc,rc,rv;
  7     #define lc(x) t[x].lc
  8     #define rc(x) t[x].rc
  9     #define fa(x) t[x].fa
 10     #define rv(x) t[x].rv
 11 }t[N];
 12  
 13 bool isr(int x)//isroot
 14 {
 15     return lc(fa(x))!=x&&rc(fa(x))!=x;
 16 }
 17 bool wrt(int x){
 18     return rc(fa(x))==x;
 19 }
 20  
 21 void rev(int x){//做标记 
 22     if(!x) return;
 23     swap(lc(x),rc(x));
 24     rv(x)^=1;
 25 }
 26  
 27 void down(int x){//下传标记 
 28     if(rv(x)){
 29         rev(lc(x)),rev(rc(x));
 30     }
 31     rv(x)=0;
 32 }
 33  
 34 void rot(int x){//旋转 
 35     int y=fa(x),z=fa(y),b=(lc(y)==x)?rc(x):lc(x);
 36     if(z&&!isr(y)) (lc(z)==y?lc(z):rc(z))=x;
 37     fa(x)=z,fa(y)=x;
 38     if(b) fa(b)=y;
 39     if(lc(y)==x) rc(x)=y,lc(y)=b;
 40     else lc(x)=y,rc(y)=b;
 41 }
 42  
 43 void path(int x){//根到节点上的点都下传标记 
 44     if(!isr(x)) path(fa(x));
 45     down(x);
 46 }
 47  
 48 void spl(int x){//splay
 49     path(x);
 50     while(!isr(x)){
 51         if(!isr(fa(x))) wrt(x)==wrt(fa(x))?rot(fa(x)):rot(x);
 52         rot(x);
 53     }
 54 }
 55  
 56 void acs(int x){
 57     for(int y=0;x;y=x,x=fa(x)){
 58         spl(x),rc(x)=y;
 59     }
 60     return ;
 61 }
 62  
 63 void mrt(int x){//makeroot 
 64     acs(x),spl(x),rev(x);
 65 }
 66  
 67 int fnd(int x){//findroot
 68     acs(x),spl(x),down(x);
 69     while(lc(x)) x=lc(x),down(x);
 70     spl(x);return x;
 71 }
 72  
 73 void lk(int x,int y){//link
 74     mrt(x);
 75     if(fnd(y)==x) return ;
 76     fa(x)=y;
 77 }
 78  
 79 void cut(int x,int y){//删边 
 80     mrt(x),acs(y),spl(y);
 81     if(lc(y)!=x) return ;
 82     lc(y)=fa(x)=0; 
 83 }
 84 /*char ch;
 85 int read(){
 86     while(ch=getchar(),ch<'0'||ch>'9');
 87     int res=ch-48;
 88     while(ch=getchar(),ch>='0'&&ch<='9')
 89         res=res*10+ch-48;
 90     return res;
 91 }*/
 92  
 93 int main(){
 94     scanf("%d%d",&n,&m);
 95     /*n=read(),m=read();*/
 96     for(int i=1;i<=m;i++){
 97         /*while(ch=getchar(),ch<'A'||ch>'Z');*/
 98         int x,y;
 99         char a[10];
100         scanf("%s",a+1);
101         scanf("%d%d",&x,&y);
102         if(a[1]=='Q'){
103             if(fnd(x)==fnd(y)) cout<<"Yes"<<endl;
104             else cout<<"No"<<endl;
105         }
106         else if(a[1]=='C') lk(x,y);
107         else cut(x,y);
108     }
109     return 0;
110 }
复制代码

 



如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
posted @   YHXo  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示