luogu P3707 [SDOI2017]相關分析
阿新 • • 發佈:2018-11-06
維護 double int mod n) ace pac new spa ,然後再是區間加\((s,t)\)的操作,至於修改的話,用上平方和公式就很吼辣\(\sum_{i=1}^n i^2=\frac{n(n+1)(2n+1)}{6}\)
傳送門
對於題目要求的東西,考慮拆開懶得拆了 ,可以發現有\(\sum x\sum y\sum x^2\sum xy\)四個變量影響最終結果,考慮維護這些值
下面記\(l,r\)為區間兩端點
首先是區間加操作,可以這樣維護\[\sum(x+s)=\sum x+(r-l+1)s\]\[\sum(y+s)=\sum y+(r-l+1)s\]\[\sum(x+s)^2=\sum x^2+2s\sum x+(r-l+1)s^2\]\[\sum(x+s)(y+t)=\sum xy+s\sum y+t\sum x+(r-l+1)st\]
然後是區間修改,區間修改可以看做先把所有\(x_i,y_i\)變成\(i\)
於是會修改成這樣\[\sum x=\sum y=(r-l+1)(l+r)/2\]\[\sum x^2=\sum xy=\sum_{i=1}^r i^2-\sum_{i=1}^{l-1} i^2\]
然後求出詢問區間的上述四個值,代入你所求的公式就行了
#include<bits/stdc++.h> #define LL long long #define il inline #define re register #define db double #define eps (1e-5) using namespace std; const int N=120000+10; il LL rd() { LL x=0,w=1;char ch=0; while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();} while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();} return x*w; } struct node { db x,y,xx,xy; node(){x=y=xx=xy=0;} node operator + (const node &b) const { node an,a=*this; an.x=a.x+b.x,an.y=a.y+b.y,an.xx=a.xx+b.xx,an.xy=a.xy+b.xy; return an; } }tr[N<<2],nw; db lz[N<<2][3],aa[N][2]; int n,m; #define lc (o<<1) #define rc ((o<<1)|1) #define mid ((l+r)>>1) il db sgmn2(db n){return n*(n+1)*(2*n+1)/6;} il void ad(int o,int l,int r,db s,db t) { db len=r-l+1; tr[o].xx+=s*tr[o].x*2+s*s*len; tr[o].xy+=s*tr[o].y+t*tr[o].x+s*t*len; tr[o].x+=len*s; tr[o].y+=len*t; lz[o][1]+=s,lz[o][2]+=t; } il void cg(int o,int l,int r) { db len=r-l+1; lz[o][1]=lz[o][2]=0; tr[o].x=tr[o].y=len*(db)(l+r)/2.0; tr[o].xx=tr[o].xy=sgmn2(r)-sgmn2(l-1); lz[o][0]=1; } il void psdn(int o,int l,int r) { if(lz[o][0]) cg(lc,l,mid),cg(rc,mid+1,r); ad(lc,l,mid,lz[o][1],lz[o][2]),ad(rc,mid+1,r,lz[o][1],lz[o][2]); lz[o][0]=lz[o][1]=lz[o][2]=0; } void bui(int o,int l,int r) { if(l==r){tr[o].x=aa[l][0],tr[o].y=aa[l][1],tr[o].xx=tr[o].x*tr[o].x,tr[o].xy=tr[o].x*tr[o].y;return;} bui(lc,l,mid),bui(rc,mid+1,r); tr[o]=tr[lc]+tr[rc]; } void modif1(int o,int l,int r,int ll,int rr,db s,db t) { if(ll<=l&&r<=rr) { ad(o,l,r,s,t); //psdn(o,l,r); return; } psdn(o,l,r); if(ll<=mid) modif1(lc,l,mid,ll,rr,s,t); if(rr>mid) modif1(rc,mid+1,r,ll,rr,s,t); tr[o]=tr[lc]+tr[rc]; } void modif2(int o,int l,int r,int ll,int rr,db s,db t) { if(ll<=l&&r<=rr) { cg(o,l,r);ad(o,l,r,s,t); //psdn(o,l,r); return; } psdn(o,l,r); if(ll<=mid) modif2(lc,l,mid,ll,rr,s,t); if(rr>mid) modif2(rc,mid+1,r,ll,rr,s,t); tr[o]=tr[lc]+tr[rc]; } node quer(int o,int l,int r,int ll,int rr) { if(ll<=l&&r<=rr) return tr[o]; psdn(o,l,r); node an; if(ll<=mid) an=an+quer(lc,l,mid,ll,rr); if(rr>mid) an=an+quer(rc,mid+1,r,ll,rr); tr[o]=tr[lc]+tr[rc]; return an; } int main() { n=rd(),m=rd(); for(int i=1;i<=n;i++) aa[i][0]=rd(); for(int i=1;i<=n;i++) aa[i][1]=rd(); bui(1,1,n); while(m--) { int op=rd(),l=rd(),r=rd(); if(op==1) { nw=quer(1,1,n,l,r); db len=r-l+1,gx=nw.x/len,gy=nw.y/len; printf("%.6lf\n",(nw.xy-gx*nw.y-gy*nw.x+gx*gy*len)/(nw.xx-2*gx*nw.x+gx*gx*len)); } else if(op==2) { db s=rd(),t=rd(); modif1(1,1,n,l,r,s,t); } else { db s=rd(),t=rd(); modif2(1,1,n,l,r,s,t); } } return 0; }
luogu P3707 [SDOI2017]相關分析