【codevs 2981】题解

#include<cstdio>
#define maxn 1000005
int n, m;
int a[maxn],c[maxn];
void update(int u,int add)
{
	while(u<=n)
	{
		c[u]+=add;
		u=u+(u&(-u));
	}
}
int sum(int u)
{
	int ans=0;
	while(u>0)
	{
		ans+=c[u];
		u=u-(u&(-u));
	}
	return ans;
}
int main()
{
	int k,x,y,z;
	char s[55];
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%s",&k,s);
		a[k]=1;
	}
	for(int i=1;i<=1000000;i++)
	{
		for(int j=i;j>=i-(i&(-i))+1;j--)
		c[i]+=a[j];		
	}
	
	scanf("%d",&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&x,&y,&z);
		if(x>y)
		{
			int t=x;x=y;y=t;
		}
		if(z>0)
		{
			for(int j=y+z;j>=x+z;j--)
			{
				update(j,a[j-z]-a[j]);
				a[j]=a[j-z];
			}
			for(int j=x;j<x+z;j++)
			{
				update(j,0-a[j]);
				a[j]=0;
			}
			
		}
		if(z<0)
		{
			z=-z;
			for(int j=x-z;j<=y-z;j++)
			{
				update(j,a[j+z]-a[j]);
				a[j]=a[j+z];
			}
			for(int j=y+z;j>y;j--)
			{
				update(j,0-a[j]);
				a[j]=0;
			}
		}
	}
	scanf("%d",&k);
	for(int i=1;i<=k;i++)
	{
		scanf("%d%d",&x,&y);
		printf("%d\n",sum(y)-sum(x-1));
	}
	return 0;
}

你可能感兴趣的:(算法,线段树)