然而又是一道road= =上一道是2750……

  下次不要一看期望题就弃疗么……

  期望题≠不可做题……!!

  其实在这题中,期望就是(所有情况下 权值之和)/(总方案数)

  因为是等概率抽取区间啊= =2333

  然而分母很好搞,直接就能算出来,所以我们要来搞分子……

  分子其实是个这玩意:$$\sum_{i=l}^{r} v[i]*(i-l+1)*(r-i+1)$$
  (我不会告诉你一开始我没加“+1”……)

  然而我一开始直接用“几何意义”之类的鬼玩意想往上套,果断跪了Orz

  膜拜了zyf的题解,其实正确姿势是这样的!$$\begin{aligned} \sum_{i=l}^{r} v[i]*(i-l+1)*(r-i+1) &= \sum_{i=l}^{r} v[i]*[(r-l-l*r+1)+i*(l+r)-i^2] \\ &=\sum_{i=l}^{r} \big (v[i]*(r-l-l*r+1) + v[i]*i*(l+r)-v[i]*i^2 \big ) \end{aligned}$$

  然后知道了这个能干嘛?…………其实………… l 和 r 就是询问的 l 和 r ,所以我们只需要维护与 i 相关的项,即$\sum v[i]$、$\sum v[i]*i$和$\sum v[i]*i^2$就可以计算答案啦~(然而蒟蒻没想到……T^T

  嗯……怎么维护?合并就是直接加嘛= =反正只跟坐标相关,然后对整个区间都add一个值?……这是数学问题不要问我>_>  (其实我也不会

 

WA:在upd的时候,由于运算时出现了l*r这个不和谐的项……所以传进去的 l 和 r 得是long long

  1 /**************************************************************
  2     Problem: 2752
  3     User: Tunix
  4     Language: C++
  5     Result: Accepted
  6     Time:3712 ms
  7     Memory:16904 kb
  8 ****************************************************************/
  9  
 10 //BZOJ 2752
 11 #include<cstdio>
 12 #include<cstring>
 13 #include<cstdlib>
 14 #include<iostream>
 15 #include<algorithm>
 16 #define rep(i,n) for(int i=0;i<n;++i)
 17 #define F(i,j,n) for(int i=j;i<=n;++i)
 18 #define D(i,j,n) for(int i=j;i>=n;--i)
 19 #define pb push_back
 20 using namespace std;
 21 typedef long long LL;
 22 inline LL getint(){
 23     LL r=1,v=0; char ch=getchar();
 24     for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1;
 25     for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch;
 26     return r*v;
 27 }
 28 const int N=100010;
 29 /*******************template********************/
 30 int n,m;
 31 struct node{
 32     LL num[4],ad;
 33     node(){F(i,0,3) num[i]=0; ad=0;}
 34 }t[N<<2];
 35  
 36 node maintain(node L,node R){
 37     node tmp;
 38     F(i,1,3) tmp.num[i]=L.num[i]+R.num[i];
 39     return tmp;
 40 }
 41 #define mid (l+r>>1)
 42 #define L (o<<1)
 43 #define R (o<<1|1)
 44 void upd(int o,LL l,LL r,LL v){
 45     t[o].ad+=v;
 46     t[o].num[1]+=v*(r-l+1);
 47     t[o].num[2]+=v*(r+l)*(r-l+1)/2;
 48     t[o].num[3]+=v*(r*(r+1)*(2*r+1)-(l-1)*l*(2*l-1))/6;//数学没学好QAQ
 49 }
 50 void Push_down(int o,int l,int r){
 51     if (t[o].ad){
 52         upd(L,l,mid,t[o].ad);
 53         upd(R,mid+1,r,t[o].ad);
 54         t[o].ad=0;
 55     }
 56 }
 57 void update(int o,int l,int r,int ql,int qr,LL v){
 58     if (ql<=l && qr>=r) upd(o,l,r,v);
 59     else{
 60         Push_down(o,l,r);
 61         if (ql<=mid) update(L,l,mid,ql,qr,v);
 62         if (qr>mid) update(R,mid+1,r,ql,qr,v);
 63         t[o]=maintain(t[L],t[R]);
 64     }
 65 }
 66 node query(int o,int l,int r,int ql,int qr){
 67     if (ql<=l && qr>=r) return t[o];
 68     else{
 69         Push_down(o,l,r);
 70         node ans;
 71         if (ql<=mid) ans=maintain(ans,query(L,l,mid,ql,qr));
 72         if (qr>mid) ans=maintain(ans,query(R,mid+1,r,ql,qr));
 73         return ans;
 74     }
 75 }
 76 inline LL gcd(LL a,LL b){return b ? gcd(b,a%b) : a;}
 77 void solve(LL fz,LL fm){
 78     fm=fm*(fm+1)/2;
 79     LL d=gcd(abs(fz),fm);
 80 //  cout << fz <<" "<<fm<<' '<<d<<endl;
 81     fz/=d; fm/=d;
 82     printf("%lld/%lld\n",fz,fm);
 83 }
 84 int main(){
 85 #ifndef ONLINE_JUDGE
 86     freopen("2752.in","r",stdin);
 87     freopen("2752.out","w",stdout);
 88 #endif
 89     n=getint()-1; m=getint();
 90     char cmd[5];
 91     F(i,1,m){
 92         scanf("%s",cmd);
 93         LL l=getint(),r=getint()-1,v;
 94         if (cmd[0]=='C'){
 95             v=getint();
 96             update(1,1,n,l,r,v);
 97         }else{
 98             node ans=query(1,1,n,l,r);
 99             LL fz=ans.num[1]*(r-l-l*r+1)+ans.num[2]*(l+r)-ans.num[3];
100             solve(fz,r-l+1);
101         }
102     }
103     return 0;
104 }
View Code

相关文章: