树状数组30分求助
查看原帖
树状数组30分求助
120362
Priori_Incantatem楼主2020/12/14 15:19

RT,调一上午了

树状数组第 k (k[106,106])k\space(k \in [-10^6,10^6]) 个位置维护当 x=kx=k 是满足的不等式个数

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int Maxn=100000+10;
const int Maxm=2000010;
struct node{
	int l,r; // 储存不等式的解集区间
}g[Maxn];
int sum[Maxm];
bool vis[Maxn];
int n,m,q,cnt;
inline int read()
{
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
	while(ch>='0' && ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
	return s*w;
}
inline int lowbit(int x)
{
	return x&(-x);
}
void modify(int x,int k)
{
	while(x<=n)
	sum[x]+=k,x+=lowbit(x);
}
int query(int x)
{
	int ret=0;
	while(x)
	ret+=sum[x],x-=lowbit(x);
	return ret;
}
int main()
{
//	freopen("in.txt","r",stdin);
//	freopen("out.txt","w",stdout);
	q=read();
	n=2000001,m=1000001; // 整体往右平移 m 个位置
	while(q--)
	{
		char s[10];
		scanf("%s",s);
		if(s[0]=='A')
		{
			int a=read(),b=read(),c=read();
			c-=b,vis[++cnt]=1;
			if(a==0)
			{
				if(c<0)g[cnt].l=1,g[cnt].r=n;
				else g[cnt].l=g[cnt].r=0; // l=r=0 表示在范围内无解
			}
			else
			{
				if(a>0)
				{
					g[cnt].l=c/a+1+m;
					g[cnt].r=n;
					if(g[cnt].l>n)
					g[cnt].l=g[cnt].r=0;
					if(g[cnt].l<1)
					g[cnt].l=1;
				}
				else
				{
					g[cnt].r=c/a+m;
					if(c%a==0)g[cnt].r--;
					g[cnt].l=1;
					if(g[cnt].r<1)
					g[cnt].l=g[cnt].r=0;
					if(g[cnt].r>n)
					g[cnt].r=n;
				}
			}
			if(!g[cnt].l)continue;
			modify(g[cnt].l,1);
			if(g[cnt].r<n)
			modify(g[cnt].r+1,-1);
			continue;
		}
		if(s[0]=='D')
		{
			int pos=read();
			if(!vis[pos])continue; // 避免多次删除导致出错
			vis[pos]=0;
			if(!g[pos].l)continue;
			modify(g[pos].l,-1);
			if(g[pos].r<n)
			modify(g[pos].r+1,1);
		}
		else
		{
			int k=read();
			printf("%d\n",query(k+m));
		}
	}
	return 0;
}
2020/12/14 15:19
加载中...