[haoi2012]高速公路
这种要求概率期望的题其实就是另一种计数题。
对于此题我们要对每个点分别计算贡献的话,每个点的贡献为左边点的数目加1的和乘右面点的数量乘这个点的权值。
不是很难,但如果没推出数学公式的话,考场gg有可能。
#include<iostream> #include<algorithm> #include<cstring> #include<vector> #include<string> #include<map> #include<cstdlib> #include<cmath> #include<cstdio> #include<ctime> #include<queue> using namespace std; #define LL long long #define FILE "dealing" #define eps 1e-10 #define db double #define pii pair<LL,LL> #define up(i,j,n) for(LL i=j;i<=n;i++) LL read(){ LL x=0,f=1,ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-'0',ch=getchar(); return x*f; } const LL maxn=1000000,mod=1000000007,inf=1000000007; bool cmin(LL& a,LL b){return a>b?a=b,true:false;} bool cmax(LL& a,LL b){return a<b?a=b,true:false;} LL n,m; LL sum[maxn],delet[maxn],siz[maxn],sum2[maxn],sum3[maxn]; LL L,R,key; void updata(LL x){ sum[x]=sum[x<<1]+sum[x<<1|1]; sum2[x]=sum2[x<<1]+sum2[x<<1|1]; sum3[x]=sum3[x<<1]+sum3[x<<1|1]; } LL g(LL x){return (x*(x+1)/2*(2*x+1))/3;} void add(LL x,LL c,LL l,LL r){ sum[x]+=siz[x]*c; delet[x]+=c; sum2[x]+=((r+1)*r/2-(l-1)*l/2)*c; sum3[x]+=(g(r)-g(l-1))*c; } void pushdown(LL x,LL l,LL r){ LL mid=(l+r)>>1; if(delet[x])add(x<<1,delet[x],l,mid),add(x<<1|1,delet[x],mid+1,r),delet[x]=0; } struct node{ LL sum1,sum2,sum3; node(LL sum1=0,LL sum2=0,LL sum3=0):sum1(sum1),sum2(sum2),sum3(sum3){} }; node operator+(node a,node b){return node(a.sum1+b.sum1,a.sum2+b.sum2,a.sum3+b.sum3);} node query(LL l,LL r,LL o){ if(l>R||r<L)return 0; if(l>=L&&r<=R)return node(sum[o],sum2[o],sum3[o]); LL mid=(l+r)>>1; pushdown(o,l,r); return query(l,mid,o<<1)+query(mid+1,r,o<<1|1); } node Query(LL l,LL r){ L=l,R=r; return query(1,n,1); } void change(LL l,LL r,LL o){ if(l>R||r<L)return; if(l>=L&&r<=R){add(o,key,l,r);return;} LL mid=(l+r)>>1; pushdown(o,l,r); change(l,mid,o<<1); change(mid+1,r,o<<1|1); updata(o); } void Change(LL l,LL r,LL del){ L=l,R=r,key=del; change(1,n,1); } void prepare(LL l,LL r,LL o){ siz[o]=r-l+1; if(l==r)return; LL mid=(l+r)>>1; prepare(l,mid,o<<1); prepare(mid+1,r,o<<1|1); } LL gcd(LL a,LL b){return !b?a:gcd(b,a%b);} char s[10]; int main(){ freopen(FILE".in","r",stdin); freopen(FILE".out","w",stdout); n=read(),m=read();n--; prepare(1,n,1); up(i,1,m){ scanf("%s",s);LL x=read(),y=read(); if(s[0]=='C'){ key=read(); Change(x,y-1,key); } else { node ans=Query(x,y-1); //printf("%lld %lld %lld\n",ans.sum1,ans.sum2,ans.sum3); LL a=ans.sum1*(y-x*(y))+ans.sum2*(x+y-1)-ans.sum3; LL b=(1+y-x)*(y-x)/2; LL d=gcd(a,b); printf("%I64d/%I64d\n",a/d,b/d); } } return 0; }