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)。对于加法操作,没有任何输出。

样例输入

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
数据范围与提示

在所有测试点中,1⩽t1​⩽3,1⩽t2​⩽4,1⩽t3​⩽2。不同的 t1​,t2​,t3​ 对应的特殊限制如下:

  • 对于 t1​=1 的测试点,满足 a=1;
  • 对于 t1​=2 的测试点,满足 ∣a∣=1;
  • 对于 t1​=3 的测试点,满足 ∣a∣⩽109;
  • 对于 t2​=1 的测试点,满足 0⩽b,k⩽30;
  • 对于 t2​=2 的测试点,满足 0⩽b,k⩽100;
  • 对于 t2​=3 的测试点,满足 0⩽b,k⩽n;
  • 对于 t2​=4 的测试点,满足 0⩽b,k⩽30n;
  • 对于 t3​=1 的测试点,保证所有询问操作都在所有修改操作之后;
  • 对于 t3​=2 的测试点,不保证询问操作和修改操作的先后顺序。

本题共 25 个测试点,每个测试点 4 分。各个测试点的数据范围如下:

测试点编号n≤t1​t2​t3​
110312
2100322
32000322
44000132
56000331
68000232
79000342
810000332
930000342
1050000341
1160000332
1265000242
1370000342
14200000342
15300000242
16400000342
17500000332
18600000342
19700000342
20800000142
21900000242
22930000332
23960000341
24990000332
251000000342

代码实现:

#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<random>
#include<bitset>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
// #pragma GCC optimize(2)
using namespace std;
#define MAXN 1000005
#define LL long long
#define ULL unsigned long long
#define ENDL putchar('\n')
#define DB double
#define lowbit(x) (-(x) & (x))
#define FI first
#define SE second
int xchar() {
	static const int maxn = 1000000;
	static char b[maxn];
	static int pos = 0,len = 0;
	if(pos == len) pos = 0,len = fread(b,1,maxn,stdin);
	if(pos == len) return -1;
	return b[pos ++];
}
// #define getchar() xchar()
LL read() {
	LL f = 1,x = 0;int s = getchar();
	while(s < '0' || s > '9') {if(s<0)return -1;if(s=='-')f=-f;s = getchar();}
	while(s >= '0' && s <= '9') {x = (x<<1) + (x<<3) + (s^48);s = getchar();}
	return f*x;
}
void putpos(LL x) {if(!x)return ;putpos(x/10);putchar((x%10)^48);}
void putnum(LL x) {
	if(!x) {putchar('0');return ;}
	if(x<0) putchar('-'),x = -x;
	return putpos(x);
}
void AIput(LL x,int c) {putnum(x);putchar(c);}

int n,m,s,o,k;
const ULL nm32 = (1ll<<32)-1;
ULL bt1[MAXN],bt2[MAXN];
set<int> st;
void addb1(ULL x,int p) { // plus
	if(!x) return ;
	x <<= (p&31); p >>= 5;
	bt1[p] += x;
	x = bt1[p] >> 32; bt1[p] &= nm32;
	if(bt1[p] != bt2[p]) st.insert(p);
	else st.erase(p);
	return addb1(x,(p+1)<<5);
}
void addb2(ULL x,int p) { // minus
	if(!x) return ;
	x <<= (p&31); p >>= 5;
	bt2[p] += x;
	x = bt2[p] >> 32; bt2[p] &= nm32;
	if(bt2[p] != bt1[p]) st.insert(p);
	else st.erase(p);
	return addb2(x,(p+1)<<5);
}
int main() {
	n = read();read();read();read();
	for(int i = 1;i <= n;i ++) {
		k = read();
		if(k == 1) {
			s = read(); o = read();
			if(s>=0) addb1(s,o);
			else addb2(-s,o);
		}
		else {
			s = read();
			o = s>>5; s &= 31;
			int me = ((bt1[o]>>s)^(bt2[o]>>s))&1;
			ULL nm = (1ll<<s)-1;
			if((bt1[o] & nm) != (bt2[o] & nm)) {
				ULL as = (bt1[o] & nm) - (bt2[o] & nm);
				AIput(((as>>s)&1)^me,'\n'); continue;
			}
			auto j = st.lower_bound(o);
			if(j == st.begin()) {
				AIput(me,'\n'); continue;
			}
			j --;
			if(bt1[*j] < bt2[*j]) me ^= 1;
			AIput(me,'\n');
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值