(2016北京集训十四)【xsy1556】股神小D - LCT

题解:

题解居然是LCT……受教了

把所有区间按照端点排序,动态维护目前有重叠的区间,用LCT维护即可。

代码:

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<cmath>
  6 #include<queue>
  7 using namespace std;
  8 typedef long long ll;
  9 struct node{
 10     int son[2],fa,sz1,sz2,rev;
 11 }t[500001];
 12 struct task{
 13     int op,u,v,x;
 14     task(int _op=0,int _u=0,int _v=0,int _x=0){
 15         op=_op,u=_u,v=_v,x=_x;
 16     }
 17     friend bool operator <(task a,task b){
 18         return a.x==b.x?a.op<b.op:a.x<b.x;
 19     }
 20 }q[500001];
 21 int n,u,v,l,r,cnt=0,top,s[500001];
 22 ll ans;
 23 int lr(int u){
 24     return t[t[u].fa].son[1]==u; 
 25 }
 26 int ntrt(int u){
 27     return t[t[u].fa].son[0]==u||t[t[u].fa].son[1]==u;
 28 }
 29 void pushup(int u){
 30     t[u].sz1=t[t[u].son[0]].sz1+t[t[u].son[1]].sz1+t[u].sz2+1;
 31 }
 32 void getrev(int u){
 33     swap(t[u].son[0],t[u].son[1]);
 34     t[u].rev^=1;
 35 }
 36 void pd(int u){
 37     if(t[u].rev){
 38         if(t[u].son[0])getrev(t[u].son[0]);
 39         if(t[u].son[1])getrev(t[u].son[1]);
 40         t[u].rev=0;
 41     }
 42 }
 43 void rotate(int u){
 44     int f=t[u].fa,ff=t[f].fa,ch=lr(u);
 45     if(ntrt(f))t[ff].son[t[ff].son[1]==f]=u;
 46     t[f].son[ch]=t[u].son[ch^1];
 47     t[t[f].son[ch]].fa=f;
 48     t[u].son[ch^1]=f;
 49     t[f].fa=u;
 50     t[u].fa=ff;
 51     pushup(f);
 52     pushup(u);
 53 }
 54 void splay(int u){
 55     int now=u;
 56     s[top=1]=now;
 57     while(ntrt(now))s[++top]=now=t[now].fa;
 58     while(top)pd(s[top--]);
 59     while(ntrt(u)){
 60         int f=t[u].fa,ff=t[f].fa;
 61         if(ntrt(f)){
 62             rotate(lr(u)==lr(f)?f:u);
 63         }
 64         rotate(u);
 65     }
 66 }
 67 void access(int u){
 68     for(int now=0;u;now=u,u=t[u].fa){
 69         splay(u);
 70         t[u].sz2+=t[t[u].son[1]].sz1-t[now].sz1;
 71         t[u].son[1]=now;
 72         pushup(u);
 73     }
 74 }
 75 void makert(int u){
 76     access(u);
 77     splay(u);
 78     getrev(u);
 79 }
 80 void link(int x,int y){
 81     makert(x);
 82     makert(y);
 83     ans+=(ll)t[x].sz1*t[y].sz1;
 84     t[y].fa=x;
 85     t[x].sz2+=t[y].sz1;
 86     pushup(x);
 87 }
 88 void cut(int x,int y){
 89     makert(x);
 90     access(y);
 91     splay(y);
 92     t[x].fa=t[y].son[0]=0;
 93     pushup(y);
 94 }
 95 int main(){
 96     scanf("%d",&n);
 97     for(int i=1;i<n;i++){
 98         scanf("%d%d%d%d",&u,&v,&l,&r);
 99         q[++cnt]=(task){0,u,v,l};
100         q[++cnt]=(task){1,u,v,r};
101     }
102     sort(q+1,q+cnt+1);
103     for(int i=1;i<=cnt;i++){
104         if(!q[i].op)link(q[i].u,q[i].v);
105         else cut(q[i].u,q[i].v);
106     }
107     printf("%lld",ans);
108     return 0;
109 }

猜你喜欢

转载自www.cnblogs.com/dcdcbigbig/p/9696743.html
LCT