JZYZOJ1527 [haoi2012]高速公路 线段树 期望

时间:2022-12-17 09:14:31

http://172.20.6.3/Problem_Show.asp?id=1527

日常线段树的pushdown写挂,果然每次写都想得不全面,以后要注意啊……
求期望部分也不熟练,和平均数搞混也是orz,我已经是个期望都求不出来的废人了。
这道题显然(大概)每个段的贡献是val[i]*(y-i+1)*(i-x+1);
整体来说算是一看就是线段树的题。

代码

JZYZOJ1527 [haoi2012]高速公路 线段树 期望JZYZOJ1527 [haoi2012]高速公路 线段树 期望
 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 }
View Code