http://172.20.6.3/Problem_Show.asp?id=1527
日常线段树的pushdown写挂,果然每次写都想得不全面,以后要注意啊……
求期望部分也不熟练,和平均数搞混也是orz,我已经是个期望都求不出来的废人了。
这道题显然(大概)每个段的贡献是val[i]*(y-i+1)*(i-x+1);
整体来说算是一看就是线段树的题。
代码
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 using namespace std; 8 #define lc x*2 9 #define rc x*2+1 10 const int maxn=1<<18; 11 long long n,m;char ch[2]={}; 12 struct seg{ 13 long long l,r,v,w,v1,v2,w1,w2; 14 seg(){l=r=v1=v2=w1=w2=v=w=0;} 15 }e[maxn]; 16 long long v1,v2,v3; 17 void pushdown(long long x,long long v){ 18 if(v!=0){ 19 long long siz=e[x].r-e[x].l+1; 20 e[x].v+=siz*v; 21 e[x].w1+=e[x].v1*v; 22 e[x].w2+=e[x].v2*v; 23 e[x].w+=v; 24 } 25 } 26 void doit(long long x){ 27 pushdown(lc,e[x].w); 28 pushdown(rc,e[x].w); 29 e[x].w=0; 30 } 31 void pushup(long long x){ 32 if(e[x].l<e[x].r){ 33 e[x].v=e[lc].v+e[rc].v; 34 e[x].w1=e[lc].w1+e[rc].w1; 35 e[x].w2=e[lc].w2+e[rc].w2; 36 } 37 } 38 void cha(long long x,long long l,long long r,long long w){ 39 if(l<=e[x].l&&e[x].r<=r){ 40 pushdown(x,w); 41 return; 42 }doit(x); 43 long long mid=(e[x].l+e[x].r)/2; 44 if(l<=mid)cha(lc,l,r,w); 45 if(r>mid)cha(rc,l,r,w); 46 pushup(x); 47 } 48 void sum(long long x,long long l,long long r){ 49 if(l<=e[x].l&&e[x].r<=r){ 50 v1+=e[x].v;v2+=e[x].w1;v3+=e[x].w2; 51 return; 52 }doit(x); 53 long long mid=(e[x].l+e[x].r)/2; 54 if(l<=mid)sum(lc,l,r); 55 if(r>mid)sum(rc,l,r); 56 pushup(x); 57 } 58 void build(long long x,long long l,long long r){ 59 e[x].l=l;e[x].r=r; 60 if(l==r){ 61 e[x].v1=l;e[x].v2=l*l;return; 62 } 63 long long mid=(l+r)/2; 64 build(lc,l,mid); 65 build(rc,mid+1,r); 66 e[x].v1=e[lc].v1+e[rc].v1;e[x].v2=e[lc].v2+e[rc].v2; 67 } 68 long long gcd(long long x,long long y){ 69 while(y){ 70 long long w=y;y=x%y;x=w; 71 } 72 return x; 73 } 74 int main(){ 75 build(1,1,1<<17); 76 scanf("%I64d%I64d",&n,&m); 77 long long x,y,v; 78 for(int i=1;i<=m;i++){ 79 scanf("%s",&ch); 80 if(ch[0]=='C'){ 81 scanf("%I64d%I64d%I64d",&x,&y,&v); 82 cha(1,x,y-1,v); 83 } 84 else{ 85 scanf("%I64d%I64d",&x,&y); 86 v1=v2=v3=0;sum(1,x,y-1); 87 long long ans=v1*(y-x*y)+v2*(x+y-1)-v3; 88 long long z=y-x;long long zong=z*(z+1)/2; 89 long long w=gcd(ans,zong); 90 printf("%I64d/%I64d\n",ans/w,zong/w); 91 } 92 } 93 return 0; 94 }