URAL 1855. Trade Guilds of Erathia

URAL 1855. Trade Guilds of Erathia_第1张图片URAL 1855. Trade Guilds of Erathia_第2张图片

题意:很多段路,每一段有路费。给定一个区间,求区间内任意两点之间的花费总和的平均值。

比如 establish 2 4   就是求 (2到3的路费+3到4的路费+2到4的路费)/3   。

如果只维护区间的路费和,会超时,每次询问都要计算很多次。

假设要求的区间是 L到R ,假设某线段以K为左端点(L<=K<R),则这条线段计算次数为 ( K-L+1 )*(R-K)=-K*K+(L+R-1)*K +R(1-L)

设这条线段花费为S这条线段在本次内对总和的贡献为  -S*K*K +(L+R-1)*S*K +R(1-L)*S 

对于所有线段,令K从L变化到R-1  只需要维护每个区间的 S*K*K  , S*K  ,   S的和,然后乘上系数。

   

#define FOR(i,n) for(long long (i)=1;(i)<=(n);(i)++)
#define For(i,n) for(long long (i)=0;(i)<(n);(i)++)
#define maxn 100005
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1 
#define cnt l,r,rt
#define LL long long
using namespace std;
LL sum[maxn<<2];
LL sumk[maxn<<2];
LL sumkk[maxn<<2];
LL add[maxn<<2];
LL multi[maxn<<2][3];
void PushUp(int rt){
	sum[rt]=sum[rt<<1]+sum[rt<<1|1];
	sumk[rt]=sumk[rt<<1]+sumk[rt<<1|1];
	sumkk[rt]=sumkk[rt<<1]+sumkk[rt<<1|1];
}
void maintain(int rt,LL Add){
	sum[rt]+=Add*multi[rt][0];
	sumk[rt]+=Add*multi[rt][1];
	sumkk[rt]+=Add*multi[rt][2];
}
void PushDown(int rt){
	if(add[rt]){
		add[rt<<1]+=add[rt];
		add[rt<<1|1]+=add[rt];
		maintain(rt<<1,add[rt]);
		maintain(rt<<1|1,add[rt]);
		add[rt]=0LL;
	}
}
void build(int l,int r,int rt){
	if(l==r){
		sum[rt]=0LL;
		sumk[rt]=0LL;
		sumkk[rt]=0LL;
		add[rt]=0LL;
		multi[rt][0]=1;
		multi[rt][1]=(LL)r;
		multi[rt][2]=(LL)r*r;
		return;
	}
	int m=(l+r)>>1;
	build(ls);
	build(rs);
	PushUp(rt);
	For(i,3){
		multi[rt][i]=multi[rt<<1][i]+multi[rt<<1|1][i];
	}
}
void update(int L,int R,LL C,int l,int r,int rt){
	if(L <= l && r <= R){
		add[rt]+=C;
		maintain(rt,C);
		return;
	}
	PushDown(rt);
	int m=(l+r)>>1;
	if(L <=m) update(L,R,C,ls);
	if(R > m) update(L,R,C,rs);
	PushUp(rt);
}
LL S,SK,SKK;
void query(int L,int R,int l,int r,int rt){
	if(L <= l && r <= R){
		S+=sum[rt];
		SK+=sumk[rt];
		SKK+=sumkk[rt];
		return;
	}
	PushDown(rt);
	int m=(l+r)>>1;
	if(L <=m) query(L,R,ls);
	if(R > m) query(L,R,rs);
}

int N,M;
int main(void)
{
	while(cin>>N>>M){
		build(1,N,1);
		FOR(q,M){
			char s[50];scanf("%s",s);
			if(s[0]=='c'){
				int a,b,c;
				scanf("%d%d%d",&a,&b,&c);
				update(a,b-1,(LL)c,1,N,1);
			}
			else{
				int a,b;
				scanf("%d%d",&a,&b);
				S=0LL;SK=0LL;SKK=0LL;
				query(a,b-1,1,N,1);
				double ANS=-SKK+((LL)a+b-1)*SK+(LL)b*(1-a)*S;
				LL D=(LL) (b-a)*(b-a+1)/2LL;
				ANS/=D;
				printf("%.10f\n",ANS); 	
			}
		}
	}
return 0;
}








你可能感兴趣的:(URAL 1855. Trade Guilds of Erathia)