[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;
}

  

posted @ 2017-02-27 10:03  CHADLZX  阅读(142)  评论(0编辑  收藏  举报