码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ[3091] 城市旅行

时间:2018-03-24 18:31:48      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:div   using   lct   shu   space   read   end   城市   oid   

  这个题一看就是LCT,但是怎么维护呢?

  考虑每一组询问的分母就是(n+1)*n/2,然后在然后看一看左子树并到整个子树之后的变化就可以知道我们维护一个lsum: (1*a[1]+2*a[2]+3*a[3]....), 那么lsum*(rsize+1)就是左子树在新字数中多出来的贡献,右子树也是类似的,

然后我们维护这个东西,就好了。

  具体来数LCT要维护size,val,sum,lsum,rsum,mark_add,mark_rev就好了

  还有个数学个公式会用到,1*n+2*(n-1)+3*(n-2)+....+(n-1)*2+1*n=n*(n+1)*(n+1)/6

  

技术分享图片
  1 #include <cmath>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <iostream>
  6 #include <algorithm>
  7 using namespace std;
  8 typedef long long LL;
  9 const int maxn=50010;
 10 int timer;
 11 int read(){
 12     int x=0,fg=1; char c=getchar();
 13     while(c<0 || c>9){if(c==-) fg=-1; c=getchar();}
 14     while(c>=0&&c<=9){x = x*10 + c-0; c=getchar();}
 15     return x*fg;
 16 }
 17 int n,m;
 18 struct Node{
 19     Node *ch[2],*f;
 20     LL lsum,rsum,sum,val,rev,add,size,exp,id;
 21     void revs(){ rev^=1; swap(lsum,rsum);}
 22     void Set(LL x){
 23         val+=x; add+=x;
 24         sum+=size*x;
 25         lsum+=x*(1+size)*size/2;
 26         rsum+=x*(1+size)*size/2;
 27         exp+=x*size*(size+1)*(size+2)/6;
 28     }
 29     void pushdown(){
 30         if(rev!=0){
 31             ch[0]->revs(); ch[1]->revs();
 32             swap(ch[0],ch[1]);
 33             rev=0;
 34         }
 35         if(add!=0){
 36             ch[0]->Set(add); ch[1]->Set(add);
 37             add=0;
 38         }
 39         return;
 40     }
 41     void pushup(){
 42         sum=val+ch[0]->sum+ch[1]->sum;
 43         int lsize=ch[0]->size,rsize=ch[1]->size;
 44         size=1+lsize+rsize;
 45         lsum=ch[0]->lsum+val*(lsize+1)+ch[1]->lsum+ch[1]->sum*(lsize+1);
 46         rsum=ch[1]->rsum+val*(rsize+1)+ch[0]->rsum+ch[0]->sum*(rsize+1);
 47         exp=ch[0]->exp+ch[1]->exp+ch[0]->lsum*(rsize+1)+ch[1]->rsum*(lsize+1)+(lsize+1)*(rsize+1)*val;
 48     }
 49     void O(){
 50         printf("  id= %lld fa= %lld ch=<%lld,%lld> val= %lld size= %lld sum= %lld lsum= %lld  rsum= %lld\n",id,f->id,ch[0]->id,ch[1]->id,val,size,sum,lsum,rsum);
 51     }
 52     void beg(int);
 53 }null[maxn];
 54 void see(string s){
 55     cout<<"see:: "<<s<<endl;
 56     bool ok=1;
 57     while(ok){ ok=0; for(int i=1;i<=n;i++) if(null[i].rev){null[i].pushdown(); ok=1;}}
 58     for(int i=1;i<=n;i++){
 59         null[i].O();
 60     }
 61 }
 62 void Node:: beg(int x){
 63     ch[0]=ch[1]=f=null; id=x;
 64     size=1; val=sum=lsum=rsum=read();
 65 }
 66 bool isroot(Node *x){return x!=x->f->ch[0] && x!=x->f->ch[1];}
 67 int Get(Node *x){return x==x->f->ch[1];}
 68 void rotate(Node *x){
 69     Node *fa=x->f,*pa=fa->f;
 70     int j=Get(x);
 71     if(!isroot(fa)) pa->ch[Get(fa)]=x;
 72     if((fa->ch[j]=x->ch[j^1])!=null) fa->ch[j]->f=fa;
 73     x->ch[j^1]=fa; x->f=pa; fa->f=x;
 74     fa->pushup(); x->pushup();
 75 }
 76 void splay(Node *x){
 77     x->pushdown();
 78     for(Node *fa=x->f;!isroot(x);rotate(x),fa=x->f){
 79         if(!isroot(fa)){
 80             fa->f->pushdown(); fa->pushdown(); x->pushdown();
 81             rotate(Get(fa)==Get(x)? fa:x);
 82         }
 83         else fa->pushdown(),x->pushdown();
 84     }
 85 }
 86 void expose(Node *x){
 87     Node *y=null;
 88     while(x!=null){
 89         splay(x);
 90         x->ch[1]=y;
 91         x->pushup();
 92         y=x; x=x->f;
 93     }
 94 }
 95 Node* find_root(Node* x){
 96     while(x->f!=null) x=x->f;
 97     return x;
 98 }
 99 void make_root(Node *x){
100     expose(x); splay(x); x->revs();
101 }
102 void link(Node *x,Node *y){
103     if(x->id==y->id || find_root(x)==find_root(y)) return;
104     make_root(x); expose(y); splay(y);
105     x->f=y;
106 }
107 void cut(Node *x,Node *y){
108     if(x->id==y->id || find_root(x)!=find_root(y)) return;
109     make_root(y); expose(x); splay(x);
110     x->ch[0]->f=null;
111     x->ch[0]=null;
112     x->pushup();
113 }
114 void Add(Node *x,Node *y,int d){
115     if(find_root(x)!=find_root(y)) return;
116     make_root(x); expose(y); splay(y);
117     y->Set(d);
118 }
119 LL GCD(LL a,LL b){
120     if(b==0) return a;
121     return GCD(b,a%b);
122 }
123 void query(Node *x,Node *y){
124     if(find_root(x)!=find_root(y)){printf("-1\n"); return;}
125     make_root(x); 
126     expose(y); 
127     splay(y);
128     int size=y->size;
129     LL a=y->exp,b=(1+size)*size/2;
130     LL gcd=GCD(a,b);
131     a/=gcd; b/=gcd;
132     printf("%lld/%lld\n",a,b);
133 }
134 int main(){
135 //    freopen("a.in","r",stdin);
136 //    freopen("1.out","w",stdout);
137     n=read(); m=read();
138     null->ch[0]=null->ch[1]=null->f=null;
139     for(int i=1;i<=n;i++) null[i].beg(i);
140     int x,y;
141     for(int i=1;i<n;i++){
142         x=read(); y=read();
143         link(null+x,null+y);
144     }
145     int opt,d;
146     for(int i=1;i<=m;i++){
147         opt=read(); x=read(); y=read();
148         if(opt==1) cut(null+x,null+y);
149         if(opt==2) link(null+x,null+y);
150         if(opt==3) d=read(),Add(null+x,null+y,d);
151         if(opt==4) query(null+x,null+y);
152     }
153 }
View Code

 

BZOJ[3091] 城市旅行

标签:div   using   lct   shu   space   read   end   城市   oid   

原文地址:https://www.cnblogs.com/FOXYY/p/8640493.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!