#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
我严重怀疑这个是过不了的