BZOJ 4821 [Sdoi2017]相关分析
题解:线段树
3操作的l,r没赋初始值竟然过了样例???
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<cstdlib> #define lo now<<1 #define ro now<<1|1 using namespace std; const int maxn=100009; int n,m; double inx[maxn],iny[maxn]; double si[maxn],si2[maxn]; struct SegmentTree{ int l,r; double x,y,xy,xx; double stx,sty,hst; double tagx,tagy,htag; }tree[maxn<<2]; void pushup(int now){ tree[now].x=tree[lo].x+tree[ro].x; tree[now].y=tree[lo].y+tree[ro].y; tree[now].xy=tree[lo].xy+tree[ro].xy; tree[now].xx=tree[lo].xx+tree[ro].xx; } void pushdown(int now){ int son; double stx=tree[now].stx; double sty=tree[now].sty; double tagx=tree[now].tagx; double tagy=tree[now].tagy; double x,y,xy,xx; int l,r; for(int i=0;i<=1;++i){ son=(now<<1|i); l=tree[son].l; r=tree[son].r; if(tree[now].hst){ tree[son].stx=stx; tree[son].sty=sty; tree[son].hst=1; tree[son].tagx=0; tree[son].tagy=0; tree[son].htag=0; tree[son].x=(r-l+1)*stx+(si[r]-si[l-1]); tree[son].y=(r-l+1)*sty+(si[r]-si[l-1]); tree[son].xy=(r-l+1)*stx*sty+(stx+sty)*(si[r]-si[l-1])+(si2[r]-si2[l-1]); tree[son].xx=(r-l+1)*stx*stx+2*stx*(si[r]-si[l-1])+(si2[r]-si2[l-1]); } if(tree[now].htag){ tree[son].htag=1; tree[son].tagx+=tagx; tree[son].tagy+=tagy; x=tree[son].x; y=tree[son].y; xy=tree[son].xy; xx=tree[son].xx; tree[son].x+=(r-l+1)*tagx; tree[son].y+=(r-l+1)*tagy; tree[son].xy+=tagx*y+tagy*x+(r-l+1)*tagx*tagy; tree[son].xx+=2*tagx*x+(r-l+1)*tagx*tagx; } } tree[now].stx=0;tree[now].sty=0;tree[now].hst=0; tree[now].tagx=0;tree[now].tagy=0;tree[now].htag=0; } void BuildTree(int now,int l,int r){ tree[now].l=l;tree[now].r=r; tree[now].hst=0; tree[now].htag=0;tree[now].tagx=0;tree[now].tagy=0; if(l==r){ tree[now].x=inx[l]; tree[now].y=iny[l]; tree[now].xy=inx[l]*iny[l]; tree[now].xx=inx[l]*inx[l]; return; } int mid=(l+r)>>1; BuildTree(lo,l,mid); BuildTree(ro,mid+1,r); pushup(now); } void Updatasec2(int now,int ll,int rr,double tagx,double tagy){ if(tree[now].l>=ll&&tree[now].r<=rr){ double x,y,xy,xx; int l=tree[now].l,r=tree[now].r; x=tree[now].x;y=tree[now].y;xy=tree[now].xy;xx=tree[now].xx; tree[now].htag=1;tree[now].tagx+=tagx;tree[now].tagy+=tagy; tree[now].x+=(r-l+1)*tagx; tree[now].y+=(r-l+1)*tagy; tree[now].xy+=tagx*y+tagy*x+(r-l+1)*tagx*tagy; tree[now].xx+=2*tagx*x+(r-l+1)*tagx*tagx; return; } pushdown(now); int mid=(tree[now].l+tree[now].r)>>1; if(ll<=mid)Updatasec2(lo,ll,rr,tagx,tagy); if(rr>mid)Updatasec2(ro,ll,rr,tagx,tagy); pushup(now); } void Updatasec3(int now,int ll,int rr,double stx,double sty){ if(tree[now].l>=ll&&tree[now].r<=rr){ int l=tree[now].l,r=tree[now].r; tree[now].tagx=0;tree[now].tagy=0;tree[now].htag=0; tree[now].stx=stx;tree[now].sty=sty;tree[now].hst=1; tree[now].x=(r-l+1)*stx+(si[r]-si[l-1]); tree[now].y=(r-l+1)*sty+(si[r]-si[l-1]); tree[now].xy=(r-l+1)*stx*sty+(stx+sty)*(si[r]-si[l-1])+si2[r]-si2[l-1]; tree[now].xx=(r-l+1)*stx*stx+2*stx*(si[r]-si[l-1])+si2[r]-si2[l-1]; // cout<<"ASD"<<l<<' '<<r<<' '<<tree[now].x<<' '<<tree[now].y<<' '<<tree[now].xy<<' '<<tree[now].xx<<endl; return; } pushdown(now); int mid=(tree[now].l+tree[now].r)>>1; if(ll<=mid)Updatasec3(lo,ll,rr,stx,sty); if(rr>mid)Updatasec3(ro,ll,rr,stx,sty); pushup(now); } double qx,qy,qxy,qxx; void Querysum(int now,int ll,int rr){ // cout<<now<<endl; if(tree[now].l>=ll&&tree[now].r<=rr){ qx+=tree[now].x; qy+=tree[now].y; qxy+=tree[now].xy; qxx+=tree[now].xx; return; } pushdown(now); int mid=(tree[now].l+tree[now].r)>>1; if(ll<=mid)Querysum(lo,ll,rr); if(rr>mid)Querysum(ro,ll,rr); } int main(){ // freopen("relative.in","r",stdin); // freopen("relative.out","w",stdout); scanf("%d%d",&n,&m); for(int i=1;i<=n;++i)scanf("%lf",&inx[i]); for(int i=1;i<=n;++i)scanf("%lf",&iny[i]); for(int i=1;i<=n;++i){ si[i]=si[i-1]+i; si2[i]=si2[i-1]+1.0*i*i; } BuildTree(1,1,n); while(m--){ // cout<<"AD"<<endl; int opty,l,r; double a,b; scanf("%d%d%d",&opty,&l,&r); if(opty==1){ // printf("now in 1\n"); qx=qy=qxy=qxx=0; Querysum(1,l,r); // cout<<qx<<' '<<qy<<' '<<qxy<<' '<<qxx<<endl; // if(fabs((r-l+1)*qxx-qx*qx)<=1e-9)exit(0); double ans=(r-l+1)*qxy-qx*qy; ans=ans/((r-l+1)*qxx-qx*qx); printf("%.10f\n",ans); } if(opty==2){ // printf("now in 2\n"); scanf("%lf%lf",&a,&b); Updatasec2(1,l,r,a,b); } if(opty==3){ // printf("now in 3\n"); scanf("%lf%lf",&a,&b); Updatasec3(1,l,r,a,b); } } return 0; }
致歉:笔者已经意识到这是一篇几乎没有价值的文章,给您的阅读带来不好的体验,并且干扰了您的搜索环境,非常抱歉!