列表

详情


NC17902. [NOI2017]整数

描述

在人类智慧的山巅,有着一台字长为1048576 位的超级计算机,著名理论计算机科学家P 博士正用它进行各种研究。不幸的是,这天台风切断了电力系统,超级计算机无法工作,而P 博士明天就要交实验结果了,只好求助于学过OI 的你. . . . . .

P 博士将他的计算任务抽象为对一个整数的操作。
具体来说,有一个整数x ,一开始为0。
接下来有n 个操作,每个操作都是以下两种类型中的一种:
• 1 a b :将x 加上整数a  2b,其中a 为一个整数,b 为一个非负整数
• 2 k :询问x 在用二进制表示时,位权为2k 的位的值(即这一位上的1 代表2k )
保证在任何时候,x  0。

输入描述

输入的第一行包含四个正整数n; t1; t2; t3,n 的含义见题目描述,t1; t2; t3 的具体含义见子任务。
接下来n 行,每行给出一个操作,具体格式和含义见题目描述。
同一行输入的相邻两个元素之间,用恰好一个空格隔开。

输出描述

对于每个询问操作,输出一行,表示该询问的答案(0 或1)。对于加法操作,没有任何输出。

示例1

输入:

10 3 1 2
1 100 0
1 2333 0
1 -233 0
2 5
2 7
2 15
1 5 15
2 15
1 -1 12
2 15

输出:

0
1
0
1
0

说明:

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 1257ms, 内存消耗: 448076K, 提交时间: 2020-03-08 13:43:17

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define LL long long
using namespace std;
const int M=3e7+31,N=1<<25;
int read()
{
	int ans=0,f=1,c=getchar();
     while(c<'0'||c>'9') 
     {
     	if(c=='-') f=-1;c=getchar();
	 }
	 while(c>='0'&&c<='9')
	 {
	 	ans=ans*10+(c-'0');
	 	c=getchar();
	 }
	 return ans*f;
}
int s1[M],s2[M],cnt;
int l,r,a,b,n,k;
void prepare(int x)
{
	if(!x) return;
	int v=x>0?x:-x,w[31];
	cnt=0;
	for(int i=30;i>=0;i--)
	{
		int now=1<<i;
		if(now&v) v-=now,w[++cnt]=i;
		if(!v) break;
	}
	l=w[cnt]+b;r=w[1]+b;
	if(x>0)
	for(int i=1;i<=cnt;i++)
	{
		int now=w[i]+b;
		while(s1[now]) s1[now++]=0,r=max(r,now);
		s1[now]=1;
	}
	else
    for(int i=1;i<=cnt;i++)
    {
    	int now=w[i]+b;
    	while(s2[now]) s2[now++]=0,r=max(r,now);
    	s2[now]=1;
	}
	
}
int tr[2*N],T,now;
void modify()
{
	for(int i=l;i<=r;i++) tr[i+N]=s1[i]^s2[i];
	for(l=(l+N)>>1,r=(r+N)>>1;l;l>>=1,r>>=1)
	for(int i=l;i<=r;i++) tr[i]=tr[i<<1]|tr[i<<1^1];
}
int find(int k)
{
	for(k+=N;k;k>>=1) if(k&1&tr[k^1])
	{
		for(k^=1;k<N;k=k<<1^tr[k<<1^1]);
		return k-N;
	}
	return -1;
}
int main()
{
	n=read();T=read();T=read();T=read();
	for(int i=1;i<=n;i++)
	{
		k=read();
		if(k==1)
		{
			a=read();b=read();
			prepare(a);
			modify();
		}
		else
		{
			a=read();
			now=find(a);
			if(s1[now]>s2[now]||now==-1) printf("%d\n",s1[a]^s2[a]);
			else printf("%d\n",s1[a]==s2[a]);
		}
	}
	return 0;
}

上一题