PKU 3468 A Simple Problem with Integers

題目:http://poj.org/problem?id=3468

題意:有N個整數,有兩個操作,一個是對給定的區間增加值,一個是查詢給定區間的和

#include <stdio.h>
const int maxn=100000;
struct SegmentTree
{
	int l, r;
	long long sum, lazy;
}st[maxn<<2];
long long z[maxn+10], ans, c;
int n, q, a, b;
char ch[3];
void BuildTree(int v, int left, int right)
{
	st[v].l=left, st[v].r=right, st[v].lazy=0;
	if (left==right)
	{
		st[v].sum=z[left];
		return;
	}
	int lc=v<<1;
	int rc=lc+1;
	int mid=(left+right)>>1;
	BuildTree(lc, left, mid);
	BuildTree(rc, mid+1, right);
	st[v].sum=st[lc].sum+st[rc].sum;
}
void Insert(int left, int right, int v, long long x)
{
	if (st[v].l==left&&st[v].r==right)
	{
		st[v].lazy+=x;
		return;
	}
	int lc=v<<1;
	int rc=lc+1;
	int mid=(st[v].l+st[v].r)>>1;
	st[v].sum+=(x*(right-left+1));
	if (left>mid) Insert(left, right, rc, x);
	else if (right<=mid) Insert(left, right, lc, x);
	else
	{
		Insert(left, mid, lc, x);
		Insert(mid+1, right, rc, x);
	}
}
long long Query(int left, int right, int v)
{
	if (st[v].l==left&&st[v].r==right)
	{
		ans+=st[v].sum+st[v].lazy*(right-left+1);
		return ans;
	}
	int lc=v<<1;
	int rc=lc+1;
	int mid=(st[v].l+st[v].r)>>1;
	st[v].sum+=st[v].lazy*(st[v].r-st[v].l+1);
	st[lc].lazy+=st[v].lazy, st[rc].lazy+=st[v].lazy;
	st[v].lazy=0;
	if (left>mid) Query(left, right, rc);
	else if (right<=mid) Query(left, right, lc);
	else Query(left, mid, lc)+Query(mid+1, right, rc);
}
int main()
{
	//freopen("in.txt", "r", stdin);
	while (scanf("%d %d", &n, &q)==2)
	{
		for (int i=1; i<=n; i++) scanf("%lld", &z[i]);
		BuildTree(1, 1, n);
		for (int i=0; i<q; i++)
		{
			scanf("%s", ch);
			if (ch[0]=='C')
			{
				scanf("%d %d %lld", &a, &b, &c);
				Insert(a, b, 1, c);
			}
			else
			{
				scanf("%d %d", &a, &b);
				ans=0;
				printf("%lld\n", Query(a, b, 1));
			}
		}
	}
	return 0;
}


發佈了24 篇原創文章 · 獲贊 3 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章