• P3822 [NOI2017] 整数


    https://www.luogu.com.cn/problem/P3822

    由于每次加一后二进制数位变化的那个均摊性质,可以把加减法分开维护,每次分成 \(\log |a_i|\) 次给某个数位加一
    然后如果进了位就暴力往后继续加一
    这样还是有点超,就压位,用 unsigned long long

    考虑怎么查询,先找到那个位置的加、减标记,异或一下,就得到了不考虑借位的答案
    考虑什么时候会借位,查询位置前面的位置(位权更小的位置)的加减标记不能全部相同,设 \(o\) 为最靠后的一个在查询位置前、且不同的位置,那么如果这一位上加的标记小于减的标记,那就寄了,需要借位,那就把答案再异或上 \(1\)

    就用 set 对于每个块(每六十四位一块)维护是否相同就行了

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<set>
    #include<assert.h>
    #define EN puts("")
    #define INT_INF ((int)0x3f3f3f3f)
    #define LL_INF ((long long)0x3f3f3f3f3f3f3f3f)
    inline long long read(){
    	register long long x=0;register int y=1;
    	register char c=getchar();
    	while(c<'0'||c>'9'){if(c=='-') y=0;c=getchar();}
    	while(c>='0'&&c<='9'){x=x*10+(c^48);c=getchar();}
    	return y?x:-x;
    }
    #define N 1000006
    #define B 64
    unsigned long long add[N*30/B+6],sub[N*30/B+6];
    std::set<int>set;
    inline void change(int b,unsigned long long *f,unsigned long long *g){
    	int block=b/B;b&=(B-1);
    	if(f[block]^g[block]) set.erase(block);
    	unsigned long long backup=f[block];
    	f[block]+=1ull<<b;
    	if(f[block]<backup) change((block+1)*B,f,g);
    	if(f[block]^g[block]) set.insert(block);
    }
    inline void change(int a,int b){
    	unsigned long long *f=add,*g=sub;
    	if(a<0) a=-a,std::swap(f,g);
    	for(int i=0;(1ll<<i)<=a;i++)if((1<<i)&a) change(b+i,f,g);
    }
    inline int ask(int k){
    	int block=k/B;k&=(B-1);
    	int ans=((add[block]^sub[block])>>k)&1;
    	unsigned long long p=add[block]&((1ull<<k)-1),q=sub[block]&((1ull<<k)-1);
    	if(p<q) ans^=1;
    	else if(p==q&&!set.empty()&&block>*(set.begin())){
    		int o=*(--set.lower_bound(block));
    		ans^=(add[o]<=sub[o]);
    	}
    	return ans;
    }
    int main(){
    	int n=read();read();read();read();
    	while(n--){
    		int op=read(),a=read();
    		if(op==1) change(a,read());
    		else printf("%d\n",ask(a));
    	}
    	return 0;
    }
    
  • 相关阅读:
    quick cocos naja
    quick cocos sprite 3 zhongfangshi
    quick cocos moveto
    quick cocos animate2
    quick cocos animate
    quick cocos schedule
    quick cocos scheduler update
    【leetcode】括号的最大嵌套深度
    【leetcode】删除某些元素后的数组均值
    【leetcode】二叉树的最小深度
  • 原文地址:https://www.cnblogs.com/suxxsfe/p/16406507.html
Copyright © 2020-2023  润新知