nsqrt(n)大力过了 咋整
查看原帖
nsqrt(n)大力过了 咋整
160663
一中益达楼主2020/7/14 16:33
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
long long n;
long long read()
{
	long long x=0;
	long long f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9') 
	{
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=(x<<3)+(x<<1)+(ch^48);
		ch=getchar();
	}
	return x*f;
}
long long block;
long long zheng[2000000*31/30+66666];
long long fu[2000000*31/30+66666];
long long addz[2000000*31/30+66666];
long long addf[2000000*31/30+66666];
long long sum[66666666];
long long getblock(long long t)
{
	return t/30LL;
}
long long getblock2(long long t)
{
	return t/block;
}
long long down2(long long t)
{
	return t*block;
}
long long up2(long long t)
{
	return down2(t+1)-1;
}
long long down(long long t)
{
	return 30LL*t;
}
void add_zheng(long long t)
{
	while(zheng[t]+addz[t]>=(1LL<<30))
	{
		bool organ=false;
		if(zheng[t]==fu[t]) organ=true;
		zheng[t]+=addz[t];
		addz[t]=0;
		addz[t+1]+=(zheng[t]>>30);
		zheng[t]&=((1LL<<30)-1);
		if(organ&&zheng[t]!=fu[t]) sum[getblock2(t)]++;
		if(!organ&&zheng[t]==fu[t]) sum[getblock2(t)]--;
		t++;
	}
	bool organ=false;
	if(zheng[t]==fu[t]) organ=true;
	zheng[t]+=addz[t];
	addz[t]=0;
	if(organ&&zheng[t]!=fu[t]) sum[getblock2(t)]++;
	if(!organ&&zheng[t]==fu[t]) sum[getblock2(t)]--;
}
void add_fu(long long t)
{
	while(fu[t]+addf[t]>=(1LL<<30))
	{
		bool organ=false;
		if(zheng[t]==fu[t]) organ=true;
		fu[t]+=addf[t];
		addf[t]=0;
		addf[t+1]+=(fu[t]>>30);
		fu[t]&=((1LL<<30)-1);
		if(organ&&zheng[t]!=fu[t]) sum[getblock2(t)]++;
		if(!organ&&zheng[t]==fu[t]) sum[getblock2(t)]--;
		t++;
	}
	bool organ=false;
	if(zheng[t]==fu[t]) organ=true;
	fu[t]+=addf[t];
	addf[t]=0;
	if(organ&&zheng[t]!=fu[t]) sum[getblock2(t)]++;
	if(!organ&&zheng[t]==fu[t]) sum[getblock2(t)]--;
}
bool cmp(long long t)
{
	bool sex=false;
	long long z=zheng[getblock(t)];
	long long f=fu[getblock(t)];
	long long x=t%30;
	z&=((1<<(x+1))-1);
	f&=((1<<(x+1))-1);
	if((z>>x)==(f>>x)) sex=true;
	z&=((1<<x)-1);
	f&=((1<<x)-1);
	if(z>f)
	{
		if(sex) return true;
		else return false;
	}
	else if(z<f)
	{
		if(sex) return false;
		else return true;
	}
	t=getblock(t);
	if(t==0)
	{
		if(sex) return true;
		else return false;
	}
	t--;
	long long dang=down2(getblock2(t));
	while(zheng[t]==fu[t]&&t!=0&&t>=dang) t--;
	if(zheng[t]==fu[t]&&t==0)
	{
		if(sex) return true;
		else return false;
	}
	else if(zheng[t]!=fu[t])
	{
		if(zheng[t]>fu[t])
		{
			if(sex) return true;
			else return false;
		}
		else
		{
			if(sex) return false;
			else return true;
		}
	}
	long long blockmm=getblock2(t);
	while(blockmm&&!sum[blockmm]) blockmm--;
	if(!sum[blockmm])
	{
		if(sex) return true;
		else return false;
	}
	else
	{
		for(long long i=up2(blockmm);i>=down2(blockmm);i--)
		{
			if(zheng[i]>fu[i])
			{
				if(sex) return true;
				else return false;
			}
			else if(zheng[i]<fu[i])
			{
				if(sex) return false;
				else return true;
			}
		}
	}
	return true;
}
int main()
{
	//freopen("2.in","r",stdin);
	//freopen("sex.out","w",stdout);
	n=read();
	read();
	read();
	read();
	block=sqrt(n*33/30);
	for(int i=1;i<=n;i++)
	{
		int opt=read();
		if(opt==1)
		{
			long long x=read();
			long long y=read();
			long long blockm=getblock(y);
			if(x>0)
			{
				addz[blockm]+=x*(1LL<<(y-down(blockm)));
				add_zheng(blockm);
			}
			else
			{
				addf[blockm]+=(-x)*(1LL<<(y-down(blockm)));
				add_fu(blockm);
			}
		}
		else
		{
			long long y=read();
			if(cmp(y)) printf("0\n");
			else printf("1\n");
		}
	}
	return 0;
}

思想就是先压30位,加减都是暴力加再判断进位

然后再给所有压位块分块便于查询。。

开O2 2.86s跑过了 最慢的点435ms

我严重怀疑这个是过不了的

2020/7/14 16:33
加载中...