现在的位置: 首页 > 综合 > 正文

wikioi1082【线段树练习 3 】

2018年01月13日 ⁄ 综合 ⁄ 共 2138字 ⁄ 字号 评论关闭

给你N个数,有两种操作:


1:给区间[a,b]的所有数增加X


2:询问区间[a,b]的数的和。

第一行一个正整数n,接下来n行n个整数,

 

再接下来一个正整数Q,每行表示操作的个数,

 

如果第一个数是1,后接3个正整数,

 

表示在区间[a,b]内每个数增加X,如果是2,

 

表示操作2询问区间[a,b]的和是多少。

对于每个询问输出一行一个答案

3

1

2

3

2

1 2 3 2

2 2 3

9

数据范围

1<=n<=200000

1<=q<=200000

如题目所示……线段树水到不能再水了……

因为发现这种水题还没过就顺手敲了个

结果因为没开long long就5连wa……真是

#include<cstdio>
#define maxn 1000000
struct treenode{
	int l,r,ls,rs,add;
	long long tot;
}tree[maxn];
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}int n,m,treesize;
long long ans;
int a[200001];
inline void update(int k)
{tree[k].tot=tree[tree[k].ls].tot+tree[tree[k].rs].tot;}
inline void downput(int k)
{
	int l=tree[k].l,r=tree[k].r,toadd=tree[k].add;
	tree[k].add=0;
	int len=r-l+1;
	if (len==1){tree[k].tot+=tree[k].add;return;}
	tree[tree[k].ls].tot+=(long long)toadd*(len-(len>>1));
	tree[tree[k].ls].add+=toadd;
	tree[tree[k].rs].tot+=(long long)toadd*(len>>1);
	tree[tree[k].rs].add+=toadd;
	update(k);
}
inline void buildtree(int l,int r)
{
	if (l>r) return;
	int now=++treesize;
	tree[now].l=l;tree[now].r=r;
	if (l==r)
	{
		tree[now].tot=a[l];
		return;
	}
	int mid=(l+r)>>1;
	tree[now].ls=treesize+1;
	buildtree(l,mid);
	tree[now].rs=treesize+1;
	buildtree(mid+1,r);
	update(now);
}
inline void addition(int k,int l,int r,int dat)
{
	downput(k);
	int x=tree[k].l,y=tree[k].r;
	if (l==x&&r==y)
	{
		tree[k].add+=dat;
		tree[k].tot+=dat*(y-x+1);
		return;
	}
	int mid=(x+y)>>1;
	if (r<=mid) addition(tree[k].ls,l,r,dat);
	else if (l>mid) addition(tree[k].rs,l,r,dat);
	else 
	{
		addition(tree[k].ls,l,mid,dat);
		addition(tree[k].rs,mid+1,r,dat);
	}
	update(k);
}
inline void ask(int k,int l,int r)
{
	int x=tree[k].l,y=tree[k].r;
	if (l==x&&r==y) {ans+=(long long)tree[k].tot;return;}
	if (tree[k].add)downput(k);
	int mid=(x+y)>>1;
	if (r<=mid) ask(tree[k].ls,l,r);
	else if (l>mid) ask(tree[k].rs,l,r);
	else
	{
		ask(tree[k].ls,l,mid);
		ask(tree[k].rs,mid+1,r);
	}
	update(k);
}
int main()
{
	n=read();
	for (int i=1;i<=n;i++)a[i]=read();
	buildtree(1,n);
	m=read();
	for (int i=1;i<=m;i++)
	{
		int opr=read(),x,y,z;
		if(opr==1)
		{
			x=read();y=read();z=read();
			addition(1,x,y,z);
		}else
		if (opr==2)
		{
			x=read(),y=read();
			ans=0;
			ask(1,x,y);
			printf("%lld\n",ans);
		}
	}
}

抱歉!评论已关闭.