bzoj2752 高速公路

 
列式子:
如果把从i号收费站到i+1号收费站之间路段编号设为i。
假如查询l号收费站到r号收费站之间的期望值。
$ Ans_{l,r} = \sum\limits_{i=l}^{r-1} v_i \times (r-i) \times (i-l+1) $
       $ = \sum\limits_{i=l}^{r-1} v_i \times (r \times i - r \times l + r - i^2 + i \times l - i) $
       $ = \sum\limits_{i=l}^{r-1} v_i \times ( - i^2 + (r + l -1) \times i + r - r \times l) $
 我们在线段树里维护$ \sum (i^2 \times v_i) $、$ \sum (i \times v_i) $、$ \sum v_i $
有公式:$ \sum\limits_{i=1}^{n} i^2 = \frac{n \times (n+1) \times (2 \times n + 1)}{6} $
然后什么东西都好办了。
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=1e5+10;
int n,m;

long long aa,ff;char cc;
long long read() {
	aa=0;cc=getchar();ff=1;
	while(cc<'0'||cc>'9') {
		if(cc=='-') ff=-1;
		cc=getchar();
	}
	while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
	return aa*ff;
}

long long gcd(long long x,long long y) {
	return y==0? x:gcd(y,x%y);
}

struct Node{
	long long l,r,pf,yc,lc,laz;
}node[4*maxn];

void bld(int pos,long long l,long long r) {
	node[pos].l=l;node[pos].r=r;
	if(l==r) return;
	long long mid=(node[pos].l+node[pos].r)>>1;
	bld(pos<<1,l,mid); bld(pos<<1|1,mid+1,r);
}

long long f(long long t) {
	return t*(t+1)/2*(2*t+1)/3;
}

void ud(int pos) {
	long long v=node[pos].laz;
	long long l=node[pos].l,r=node[pos].r;
	if(!v) return ;
	node[pos].lc+=(r-l+1)*v;
	node[pos].yc+=(l+r)*(r-l+1)/2*v;
	node[pos].pf+=(f(r)-f(l-1))*v;
	if(node[pos].l!=node[pos].r) {
		node[pos<<1].laz+=v;
		node[pos<<1|1].laz+=v;
	}
	node[pos].laz=0;
}

void chge(int pos,long long l,long long r,long long v) {
	ud(pos);
	if(node[pos].l==l&&node[pos].r==r) {
		node[pos].laz+=v;
		return;
	}
	node[pos].lc+=(r-l+1)*v;
	node[pos].yc+=(l+r)*(r-l+1)/2*v;
	node[pos].pf+=(f(r)-f(l-1))*v;
	long long mid=(node[pos].l+node[pos].r)>>1;
	if(r<=mid) chge(pos<<1,l,r,v);
	else if(l>mid) chge(pos<<1|1,l,r,v);
	else chge(pos<<1,l,mid,v),chge(pos<<1|1,mid+1,r,v);
}

long long q(int pos,long long l,long long r,long long x,long long y) {
	ud(pos);
	if(node[pos].l==l&&node[pos].r==r) 
		return node[pos].lc*(y-y*x)+(y+x-1)*node[pos].yc-node[pos].pf;
	
	long long mid=(node[pos].l+node[pos].r)>>1;
	if(r<=mid) return q(pos<<1,l,r,x,y);
	else if(l>mid) return q(pos<<1|1,l,r,x,y);
	else return q(pos<<1,l,mid,x,y)+q(pos<<1|1,mid+1,r,x,y);
}

int main() {
	n=read();m=read();
	long long l,r,ans,x,y;char op;
	bld(1,1,n-1);
	for(int i=1;i<=m;++i) {
		do op=getchar();while(op<'C'||op>'Q');
		l=read();r=read();
		if(op=='C') chge(1,l,r-1,read());
		else {
			ans=q(1,l,r-1,l,r);
			x=r-l+1;
			x=x*(x-1)/2;
			y=gcd(ans,x);
			ans/=y;x/=y;
			printf("%lld/%lld\n",ans,x);
		}
	}
	return 0;
}

  

posted @ 2017-09-28 20:58  shixinyi  阅读(142)  评论(0编辑  收藏  举报