BZOJ 4821 [Sdoi2017]相关分析 ——线段树
打开题面,看到许多$\sum$
woc,好神啊,SDOI好强啊
然后展开之后,woc,SDOI好弱啊,怎么T3出个线段树裸题啊。
最后写代码的时候,woc,SDOI怎么出个这么码农的题啊,怎么调啊。
想想自己加上考场$Debuff$是肯定写不出来的。
#include <map> #include <cmath> #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define F(i,j,k) for (int i=j;i<=k;++i) #define D(i,j,k) for (int i=j;i>=k;--i) //#define double long double #define ll long long #define mp make_pair #define maxn 400005 #define sum(x) (1LL*(x)*((x)+1)/2) #define sum2(x) (1LL*(x)*((x)+1)*(2*(x)+1)/6) double sum_x[maxn],sum_y[maxn],sum_xy[maxn],sum_xx[maxn]; double tag_x[maxn],tag_y[maxn]; bool tag_c[maxn]; int x[maxn],y[maxn]; double sumx,sumy,sumxy,sumxx; int n,m; void update(int o,int l,int r) { sum_x[o]=sum_x[o<<1]+sum_x[o<<1|1]; sum_y[o]=sum_y[o<<1]+sum_y[o<<1|1]; sum_xy[o]=sum_xy[o<<1]+sum_xy[o<<1|1]; sum_xx[o]=sum_xx[o<<1]+sum_xx[o<<1|1]; } void add_tag_x(int o,int l,int r,double s) { tag_x[o]+=s; sum_xx[o]+=1LL*s*s*(r-l+1)+2*s*sum_x[o]; sum_xy[o]+=1LL*sum_y[o]*s; sum_x[o]+=1LL*(r-l+1)*s; } void add_tag_y(int o,int l,int r,double t) { tag_y[o]+=t; sum_xy[o]+=1LL*sum_x[o]*t; sum_y[o]+=1LL*(r-l+1)*t; } void add_cov(int o,int l,int r) { sum_y[o]=sum_x[o]=sum(r)-sum(l-1); sum_xy[o]=sum_xx[o]=sum2(r)-sum2(l-1); tag_x[o]=tag_y[o]=0; tag_c[o]=true; } void pushdown(int o,int l,int r) { if (o==0||l==r) return; int mid=l+r>>1; if (tag_c[o]) { add_cov(o<<1,l,mid); add_cov(o<<1|1,mid+1,r); tag_c[o]=false; } if (tag_x[o]) { add_tag_x(o<<1,l,mid,tag_x[o]); add_tag_x(o<<1|1,mid+1,r,tag_x[o]); tag_x[o]=0; } if (tag_y[o]) { add_tag_y(o<<1,l,mid,tag_y[o]); add_tag_y(o<<1|1,mid+1,r,tag_y[o]); tag_y[o]=0; } } void st_modify(int o,int l,int r,int L,int R,double s,double t) { if (L<=l&&r<=R){add_tag_x(o,l,r,s);add_tag_y(o,l,r,t);return;} int mid=l+r>>1; pushdown(o,l,r); if (L<=mid) st_modify(o<<1,l,mid,L,R,s,t); if (R>mid) st_modify(o<<1|1,mid+1,r,L,R,s,t); update(o,l,r); } void modify(int l,int r,double s,double t) {st_modify(1,1,n,l,r,s,t);} void st_cov(int o,int l,int r,int L,int R) { if (L<=l&&r<=R){add_cov(o,l,r);return;} int mid=l+r>>1; pushdown(o,l,r); if (L<=mid) st_cov(o<<1,l,mid,L,R); if (R>mid) st_cov(o<<1|1,mid+1,r,L,R); update(o,l,r); } void cover(int l,int r) {st_cov(1,1,n,l,r);} void st_query(int o,int l,int r,int L,int R) { if (L<=l&&r<=R){sumx+=sum_x[o],sumy+=sum_y[o],sumxx+=sum_xx[o];sumxy+=sum_xy[o];return;} int mid=l+r>>1; pushdown(o,l,r); if (R<=mid) st_query(o<<1,l,mid,L,R); else if (L>mid) st_query(o<<1|1,mid+1,r,L,R); else st_query(o<<1,l,mid,L,R),st_query(o<<1|1,mid+1,r,L,R); } double query(int l,int r) { sumx=0; sumy=0;sumxx=0; sumxy=0; double len=r-l+1; st_query(1,1,n,l,r); printf("%.10lf\n",(len*sumxy-sumx*sumy)/(len*sumxx-sumx*sumx)); } void build(int o,int l,int r) { if (l==r) { sum_x[o]=x[l]; sum_y[o]=y[l]; sum_xy[o]=1LL*x[l]*y[l]; sum_xx[o]=1LL*x[l]*x[l]; return ; } int mid=l+r>>1; build(o<<1,l,mid); build(o<<1|1,mid+1,r); update(o,l,r); } int main() { scanf("%d%d",&n,&m); F(i,1,n) scanf("%d",&x[i]); F(i,1,n) scanf("%d",&y[i]); build(1,1,n); F(i,1,m) { int opt,l,r,s,t; scanf("%d",&opt); switch(opt) { case 1: scanf("%d%d",&l,&r); query(l,r); break; case 2: scanf("%d%d%d%d",&l,&r,&s,&t); modify(l,r,(double)s,(double)t); break; case 3: scanf("%d%d%d%d",&l,&r,&s,&t); cover(l,r); modify(l,r,(double)s,(double)t); } } }