• BZOJ4942 [Noi2017]整数


    题解:

    这题有点卡常数(自己的常数大)

    每30位压成一个数

    思路1:

    每次操作拆成最多两个位置的操作

    每加一次最多会进1

    每减一次最多会退1

    然后用线段树维护最近的非0位和非满位

    然后就是区间赋值和单点修改

    好难写没写出来QWQ

    思路2:

    分两个数组记录加操作(A)和减操作(B)

    用set维护所有的不同位置

    比较两个字符串的大小即找到第一个不同的位置

    查询时分情况讨论

    A的这一位是1还是0,B的这一位是1还是0,以及AB的后缀大小情况

    讨论进位退位即可

    暴力修改即可

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<set>
    using namespace std;
    const int u=30;
    const int ux=(1<<u);
    typedef long long Lint;
    const int maxn=2000009;
    
    int n;
    int TT,t1,t2,t3;
    
    Lint A[maxn]={0};
    Lint B[maxn]={0};
    
    set<int>S;
    int cmp(int x){
    	set<int>::iterator it=S.upper_bound(x);
    	if(it==S.begin())return 0;
    	--it;
    	if(A[*it]>B[*it])return 1;
    	if(A[*it]<B[*it])return -1;
    }
    
    void pushup(int bol){
    	if(A[bol]==B[bol]){
    		if(S.count(bol))S.erase(bol);
    	}
    	if(A[bol]!=B[bol]){
    		if(!S.count(bol))S.insert(bol);
    	}
    }
    
    void print(Lint x){
    	if(x==0)return;
    	print(x>>1);
    	if(x&1)printf("1");
    	else printf("0");
    }
    
    int main(){
    	scanf("%d%d%d%d",&TT,&t1,&t2,&t3);
    	n=TT+1000;
    	
    	while(TT--){
    		int opty,y;
    		Lint x;
    		scanf("%d",&opty);
    		if(opty==1){
    			scanf("%lld%d",&x,&y);
    			++y;
    			int bol=(y-1)/u+1;
    			y-=(bol-1)*u;
    			
    			if(x>0){
    				A[bol]+=(x<<(y-1));
    				while(A[bol]>=ux){
    					A[bol+1]+=A[bol]/ux;
    					A[bol]%=ux;
    					pushup(bol);
    					++bol;
    				}
    				pushup(bol);
    			}else{
    				x=-x;
    				B[bol]+=(x<<(y-1));
    				while(B[bol]>=ux){
    					B[bol+1]+=B[bol]/ux;
    					B[bol]%=ux;
    					pushup(bol);
    					++bol;
    				}
    				pushup(bol);
    			}
    		}else{
    			scanf("%d",&y);
    			++y;
    			int bol=(y-1)/u+1;
    			y-=(bol-1)*u;
    	
    			Lint tm1=A[bol]&((1<<(y-1))-1);
    			Lint tm2=B[bol]&((1<<(y-1))-1);
    			int tm3=cmp(bol-1);
    			int r=0;
    			if(tm1==tm2){
    				r=tm3;
    			}else if(tm1<tm2){
    				r=-1;
    			}else{
    				r=1;
    			}
    			if(A[bol]&(1<<(y-1))){
    				if(B[bol]&(1<<(y-1))){
    					if(r<0)printf("1
    ");
    					else printf("0
    ");
    				}else{
    					if(r>=0)printf("1
    ");
    					else printf("0
    ");
    				}
    			}else{
    				if(B[bol]&(1<<(y-1))){
    					if(r>=0)printf("1
    ");
    					else printf("0
    ");
    				}else{
    					if(r<0)printf("1
    ");
    					else printf("0
    ");
    				}
    			}
    		}
    	}
    	return 0;
    }
    

      

    自己还是太辣鸡了
  • 相关阅读:
    spring boot 2.0.3+spring cloud (Finchley)2、搭建负载均衡Ribbon (Eureka+Ribbon+RestTemplate)
    spring boot 2.0.3+spring cloud (Finchley)1、搭建服务注册和发现组件Eureka 以及构建高可用Eureka Server集群
    windows下安装redis
    Spring注解@Resource和@Autowired的区别
    spring常用管理bean注解
    maven中package和install命令的区别
    SpringBoot打war包并部署到tomcat下运行
    使用jquery.qrcode生成二维码及常见问题解决方案
    动态生成二维码插件 jquery.qrcode.js
    Notepad++的列编辑功能
  • 原文地址:https://www.cnblogs.com/zzyer/p/8560792.html
Copyright © 2020-2023  润新知