【CDOJ】这是一道简单题

Q - 这是一道简单题

Time Limit: 100 MS     Memory Limit: 64 MB
Submit Status

出题人Acnext又要背锅了,他必须出一道大家都会做的简单题,如果有人做不出来他就得背锅,聪明的你能解决这道简单题让他避免背锅吗:

给出一个长nn的数列,以及nn个操作,操作涉及区间加法,单点查询

Input

第一行输入一个数字n,(1n50000)n,(1≤n≤50000)

第二行输入nn个正整数,第ii个数字为ai,(1ai109)ai,(1≤ai≤109),空格隔开

接下来输入nn行询问,每行输入四个数字opt,l,r,copt,l,r,c

opt=0opt=0,表示将[l,r][l,r]的数字都加cc

opt=1opt=1,表示询问arar的值(忽略l,cl,c)

Output

对于每次询问,输出一行代表答案

保证所有数据在int范围内

Sample input and output

Sample Input Sample Output
4
1 2 2 3
0 1 3 1
1 0 1 0
0 1 2 2
1 0 2 0
2
5

Hint

分块做法有加分哦

#include<algorithm>
#include<cstdio>
#include<iostream>

using namespace std;

struct SegmentTree
{
	int l,r;
	long long sum, add;
	#define l(x) tree[x].l
	#define r(x) tree[x].r
	#define sum(x) tree[x].sum
	#define add(x) tree[x].add
}	tree[1000010*4];

int a[1000010];
long long n,m;
void build(int p,int l,int r)
{
	l(p)=l;
	r(p)=r;
	if(l==r) 
	{
		sum(p)=a[l];
		return;
	}
	int mid = (l+r)/2;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	sum(p)=sum(p*2+1)+sum(p*2);
	
}
void spread(int p)
{
	if(add(p))
	{
		sum(p*2)+=add(p)*(r(p*2)-l(p*2)+1);
		sum(p*2+1)+=add(p)*(r(p*2+1)-l(p*2+1)+1);
		add(p*2)+=add(p);
		add(p*2+1)+=add(p);
		add(p)=0; 
	}
	
}
void change (int p, int l, int r, int d)
{
	if(l<=l(p)&&r>=r(p))
	{
		sum(p)+=(long long )d*(r(p)-l(p)+1);
		add(p)+=d;
		return;
	}
	spread(p);
	int mid=(l(p)+r(p))/2;
	if(l<=mid)
	{
		change(p*2,l,r,d);
	}
	if(r>mid)
	{
		change(p*2+1,l,r,d);
	}
	sum(p)=sum(p*2)+sum(p*2+1);
}

long long ask(int p, int l,int r)
{
	if(l<=l(p)&&r>=r(p))
	{
		return sum(p);
	}
	spread(p);
	int mid = (l(p)+r(p))/2;
	long long val = 0;
	if(l<=mid)	val+=ask(p*2,l,r);
	if(r>mid)	val+=ask(p*2+1,l,r);
	return val; 
}

int main()
{
	scanf("%lld",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",a+i);
	 } 
	build(1,1,n);
	while(n--)
	{	
		
		char op[2];long long  l,r,v;
		
		scanf("%s%d%d%d",op,&l,&r,&v);
		if(op[0]=='0')
		{
			change(1,l,r,v);
		}
		else
		{
			printf("%lld\n",ask(1,r,r));
		}
		
	}
}

猜你喜欢

转载自blog.csdn.net/michaelliu6/article/details/80369573