「luogu3707」[SDOI2017]相关分析
这题没什么思考难度,但比较考验码力
用线段树维护5个值:Σxi ,Σyi,Σxi2,Σyi2,Σxi*yi
注意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 }