这道题昨天晚上写好代码交了几次,都是超时,那时没想到优化,就是单纯的线段树,晚上回去想了一下,每一个节点上可增加一个标记bj,刚开始我标记的也是增量,但是意思不一样,如果当前节点的left==a,并且right==b;如果当前节点的bj不是-1就bj+=c;如果a,b表示的区间只是当前节点的一部分,就让bj=-1;然后再向子节点推,但是这样的方法只是优化了很少的一部分,由于bj=-1之后永远也只可能是-1,所以对tle影响不大!就又换了一种标记方法!

/*给每一条添加一个d变量后,我们就能在自顶向下的递归过程中,不断记录当前累积的d。因为上一层是下一层的父节点,显然父区间修改一次,子区间都会全部受影响,所以这个d在递归过程中是非递减的,当线段匹配时,就能将该线段的d修改为累积的d。

而另一个变量sum的作用就是排除了当前区间的修改后的的和,就是说该区间的和是sum+d*区间长度。*/

这一段是复制的别人的,我怕我不能正确的表达这个意思!

code:

# include<stdio.h>
struct node {
	int left,right,mid;
	__int64 bj;
	__int64 num;
}a[400001];
__int64 sum;
int st[100003];
void make(int ans1,int ans2,int step)
{
	a[step].left=ans1;
	a[step].right=ans2;
	a[step].mid=(ans1+ans2)/2;
	a[step].bj=0;
	if(ans1==ans2) {a[step].num=st[ans1];return;}
	make(ans1,a[step].mid,2*step);
	make(a[step].mid+1,ans2,2*step+1);
	a[step].num=a[2*step].num+a[step*2+1].num;
}
void update(int ans1,int ans2,int c,int step)
{
	if(a[step].left==ans1 && a[step].right==ans2) {a[step].bj+=c;return;}
	if(ans1>a[step].mid) update(ans1,ans2,c,2*step+1);
	else if(ans2<=a[step].mid) update(ans1,ans2,c,2*step);
	else 
	{
		update(ans1,a[step].mid,c,2*step);
		update(a[step].mid+1,ans2,c,2*step+1);
	}
	a[step].num=a[2*step].num+a[2*step].bj*(a[2*step].right-a[step*2].left+1);
	a[step].num+=a[2*step+1].num+a[2*step+1].bj*(a[2*step+1].right-a[step*2+1].left+1);
}
void query(int ans1,int ans2,int step,__int64 t)
{
	t+=a[step].bj;
	if(a[step].left==ans1 && ans2==a[step].right) 
	{sum+=a[step].num+(ans2-ans1+1)*t;return;}
	if(ans1>a[step].mid)  query(ans1,ans2,2*step+1,t);
	else if(ans2<=a[step].mid) query(ans1,ans2,2*step,t);
	else 
	{
		query(ans1,a[step].mid,2*step,t);
		query(a[step].mid+1,ans2,2*step+1,t);
	}
}
int main()
{
	int i,n,q,d,b,c;
	char s[3];
    scanf("%d%d",&n,&q);
		for(i=1;i<=n;i++)
			scanf("%d",&st[i]);
		make(1,n,1);
		while(q--)
		{
			scanf("%s%d%d",s,&d,&b);
			if(s[0]=='C') 
			{
				scanf("%d",&c);
				update(d,b,c,1);
			}
			else 
			{
				sum=0;
				query(d,b,1,0);
				printf("%I64d\n",sum);
			}
		}
	return 0;
}




posted on 2010-08-24 10:41  奋斗青春  阅读(624)  评论(0编辑  收藏  举报