「luogu3707」[SDOI2017]相关分析

这题没什么思考难度,但比较考验码力

用线段树维护5个值:Σxi ,Σyi,Σxi2,Σyi2,Σxi*y

注意x*y会爆int。

  1 #include<bits/stdc++.h>
  2 #define R register
  3 #define db double
  4 using namespace std;
  5 const int N=100010,oo=1e9;
  6 int n,m,ls[N<<2],rs[N<<2];
  7 db x[N],y[N],msum[N<<2];
  8 int read(){
  9     int x=0,w=1;char c=0;
 10     while(c<'0'||c>'9'){if(c=='-') w=-1;c=getchar();}
 11     while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();
 12     return x*w;
 13 }
 14 struct Node{
 15     db x,y;
 16     Node operator+(const Node& k)const{return (Node){x+k.x,y+k.y};}
 17     Node operator/(const int& k)const{return (Node){x/k,y/k};}
 18 }sum[N<<2],psum[N<<2],add[N<<2],change[N<<2];
 19 inline void pushup(int k){
 20     if(ls[k]==rs[k]) return;
 21     sum[k]=sum[k<<1]+sum[k<<1|1];
 22     psum[k]=psum[k<<1]+psum[k<<1|1];
 23     msum[k]=msum[k<<1]+msum[k<<1|1];
 24     return;
 25 }
 26 inline void dochange(int k,db s,db t){
 27     db l=ls[k],r=rs[k];
 28     sum[k]=(Node){1LL*(l+r)*(r-l+1)/2+s*(r-l+1),1LL*(l+r)*(r-l+1)/2+t*(r-l+1)};
 29     db t1=(s+r)*(s+r+1)*(s*2+r*2+1)/6-(s+l-1)*(s+l)*(s*2+l*2-1)/6;
 30     db t2=(t+r)*(t+r+1)*(t*2+r*2+1)/6-(t+l-1)*(t+l)*(t*2+l*2-1)/6;
 31     psum[k]=(Node){t1,t2};
 32     msum[k]=(r-l+1)*(s+l)*(t+l)+(r-l+1)*(r-l)/2*(s+t+l*2)+(r-l)*(r-l+1)*(r*2-l*2+1)/6;
 33     change[k]=(Node){s,t},add[k]=(Node){0,0};
 34     return;
 35 }
 36 inline void doadd(int k,db s,db t){
 37     db l=ls[k],r=rs[k];
 38     msum[k]+=s*sum[k].y+t*sum[k].x+s*t*(r-l+1);
 39     psum[k]=psum[k]+(Node){s*sum[k].x*2+s*s*(r-l+1),t*sum[k].y*2+t*t*(r-l+1)};
 40     sum[k]=sum[k]+(Node){s*(r-l+1),t*(r-l+1)};
 41     add[k]=add[k]+(Node){s,t};
 42     return;
 43 }
 44 inline void pushdown(int k){
 45     if(ls[k]==rs[k]) return;
 46     if(change[k].x<oo){
 47         dochange(k<<1,change[k].x,change[k].y);
 48         dochange(k<<1|1,change[k].x,change[k].y);
 49         change[k]=(Node){oo,oo};
 50     }
 51     doadd(k<<1,add[k].x,add[k].y);doadd(k<<1|1,add[k].x,add[k].y);
 52     add[k]=(Node){0,0};
 53     return;
 54 }
 55 void build(int k,int l,int r){
 56     ls[k]=l,rs[k]=r,change[k]=(Node){oo,oo};
 57     if(l==r){
 58         sum[k]=(Node){x[l],y[l]};
 59         psum[k]=(Node){x[l]*x[l],y[l]*y[l]};
 60         msum[k]=x[l]*y[l];
 61         return;
 62     }
 63     int mid=(l+r)>>1;
 64     build(k<<1,l,mid);build(k<<1|1,mid+1,r);
 65     pushup(k);
 66     return;
 67 }
 68 void modify1(int k,int l,int r,db s,db t){
 69     pushdown(k);
 70     if(ls[k]==l&&rs[k]==r){doadd(k,s,t);return;}
 71     int mid=(ls[k]+rs[k])>>1;
 72     if(r<=mid) modify1(k<<1,l,r,s,t);
 73     else if(l>mid) modify1(k<<1|1,l,r,s,t);
 74     else{modify1(k<<1,l,mid,s,t);modify1(k<<1|1,mid+1,r,s,t);}
 75     pushup(k);
 76     return;
 77 }
 78 void modify2(int k,int l,int r,db s,db t){
 79     pushdown(k);
 80     if(ls[k]==l&&rs[k]==r){dochange(k,s,t);return;}
 81     int mid=(ls[k]+rs[k])>>1;
 82     if(r<=mid) modify2(k<<1,l,r,s,t);
 83     else if(l>mid) modify2(k<<1|1,l,r,s,t);
 84     else{modify2(k<<1,l,mid,s,t);modify2(k<<1|1,mid+1,r,s,t);}
 85     pushup(k);
 86     return;
 87 }
 88 void que(int k,int l,int r,Node& q1,Node& q2,db& q3){
 89     pushdown(k);
 90     if(ls[k]==l&&rs[k]==r){
 91         q1=q1+sum[k],q2=q2+psum[k],q3+=msum[k];
 92         return;
 93     }
 94     int mid=(ls[k]+rs[k])>>1;
 95     if(r<=mid) que(k<<1,l,r,q1,q2,q3);
 96     else if(l>mid) que(k<<1|1,l,r,q1,q2,q3);
 97     else{que(k<<1,l,mid,q1,q2,q3);que(k<<1|1,mid+1,r,q1,q2,q3);}
 98 }
 99 db quea(int l,int r){
100     Node cursum=(Node){0,0},curpsum=(Node){0,0};
101     db curmsum=0;
102     que(1,l,r,cursum,curpsum,curmsum);
103     Node ave=cursum/(r-l+1);
104     db t1=curmsum-ave.y*cursum.x-ave.x*cursum.y+ave.x*ave.y*(r-l+1);
105     db t2=curpsum.x-ave.x*cursum.x*2+(ave.x*ave.x)*(r-l+1);
106     return t1/t2;
107 }
108 int main(){
109     int opt,t1,t2,t3,t4;
110     n=read(),m=read();
111     for(R int i=1;i<=n;i++) x[i]=read();
112     for(R int i=1;i<=n;i++) y[i]=read();
113     build(1,1,n);
114     while(m--){
115         opt=read(),t1=read(),t2=read();
116         if(opt==1){
117             printf("%.7lf\n",quea(t1,t2));
118         }else if(opt==2){
119             t3=read(),t4=read();
120             modify1(1,t1,t2,t3,t4);
121         }else{
122             t3=read(),t4=read();
123             modify2(1,t1,t2,t3,t4);
124         }
125     }
126     return 0;
127 }

 

posted @ 2018-03-16 17:56  Cupcake  阅读(262)  评论(0编辑  收藏  举报