• [NOI2017] 整数


    XL.[NOI2017] 整数

    首先可以想到一种用线段树维护每一位的方法:一个数 \(a\times2^b\) 拆成 \(\log a\) 个位置上 \(+1\),执行单点 \(+1\) 的时候如果出现进位就找到右方第一个非 \(1\) 的位置,然后单点加,区间赋 \(0\);执行减法的时候,就是找到右方第一个非 \(0\) 的位置,单点减,然后区间赋 \(1\)。(总之就是手工高精度竖式计算之类的)

    但是这样复杂度就是 \(O(n\log^2n)\),对于 \(10^6\) 不可能过。

    然后,既然是高精度算法,那就可以压位,每 \(30\) 位压一块,这样执行一次加减法都不会爆 int。加法时就找到右方第一个非满的位置,减法时就找到右方第一个非零的位置,都可以线段树上二分简单维护。

    时间复杂度 \(O(n\log n)\)

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int LG=30;
    const int MD=1<<30;
    int n;
    #define lson x<<1
    #define rson x<<1|1
    #define mid ((l+r)>>1) 
    struct SegTree{
    	int nz,nf,tag;//none-zero position,none-full position
    	SegTree(){nz=nf=tag=-1;}
    }seg[5001000];
    #define LSON lson,l,mid
    #define RSON rson,mid+1,r
    #define X x,l,r
    void MOD(int x,int l,int r,int y){if(!y)seg[x].nf=l,seg[x].nz=-1;if(y==MD-1)seg[x].nz=l,seg[x].nf=-1;seg[x].tag=y;}
    void pushdown(int x,int l,int r){if(seg[x].tag!=-1)MOD(LSON,seg[x].tag),MOD(RSON,seg[x].tag),seg[x].tag=-1;}
    void pushup(int x){if(seg[lson].nf!=-1)seg[x].nf=seg[lson].nf;else seg[x].nf=seg[rson].nf;if(seg[lson].nz!=-1)seg[x].nz=seg[lson].nz;else seg[x].nz=seg[rson].nz;}
    void upd(int x,int l,int r){if(seg[x].tag)seg[x].nz=l;else seg[x].nz=-1;if(seg[x].tag!=MD-1)seg[x].nf=l;else seg[x].nf=-1;}
    bool ADD(int x,int l,int r,int P,int y){
    	if(l>P||r<P)return false;
    	if(l==r){seg[x].tag+=y;bool ret=false;if(seg[x].tag>=MD)seg[x].tag-=MD,ret=true;upd(X);return ret;}
    	pushdown(X);bool ret=ADD(LSON,P,y)||ADD(RSON,P,y);pushup(x);return ret;
    }
    bool SUB(int x,int l,int r,int P,int y){
    	if(l>P||r<P)return false;
    	if(l==r){seg[x].tag-=y;bool ret=false;if(seg[x].tag<0)seg[x].tag+=MD,ret=true;upd(X);return ret;}
    	pushdown(X);bool ret=SUB(LSON,P,y)||SUB(RSON,P,y);pushup(x);return ret;
    }
    bool ADD1(int x,int l,int r,int P){
    	if(r<=P)return false;
    	if(l>P&&seg[x].nf==-1){MOD(X,0);return false;}
    	if(l==r){seg[x].tag++,upd(X);return true;}
    	pushdown(X);bool ret=ADD1(LSON,P)||ADD1(RSON,P);pushup(x);return ret;
    }
    bool SUB1(int x,int l,int r,int P){
    	if(r<=P)return false;
    	if(l>P&&seg[x].nz==-1){MOD(X,MD-1);return false;}
    	if(l==r){seg[x].tag--,upd(X);return true;}
    	pushdown(X);bool ret=SUB1(LSON,P)||SUB1(RSON,P);pushup(x);return ret;
    }
    void build(int x,int l,int r){if(l==r)seg[x].tag=0,seg[x].nf=l;else build(LSON),build(RSON),pushup(x);}
    bool query(int x,int l,int r,int P,int k){if(l>P||r<P)return false;if(l==r)return (seg[x].tag>>k)&1;pushdown(X);return query(LSON,P,k)||query(RSON,P,k);}
    void ADD(int a,int p){if(ADD(1,0,n+10,p,a))ADD1(1,0,n+10,p);}
    void SUB(int a,int p){if(SUB(1,0,n+10,p,a))SUB1(1,0,n+10,p);}
    void modify(int a,int b){
    	if(!a)return;
    	bool sub=false;if(a<0)a=-a,sub=true;
    	int p=b/LG;b%=LG;
    	ll A=((ll)a)<<b;
    //	printf("%lld %d %d\n",A,p,b);
    	if(!sub){ADD(A%MD,p);if(A>=MD)ADD(A/MD,p+1);}
    	else{SUB(A%MD,p);if(A>=MD)SUB(A/MD,p+1);}
    }
    bool query(int p){return query(1,0,n+10,p/LG,p%LG);}
    int read(){
    	int x=0,fl=1;char c=getchar();
    	for(;c>'9'||c<'0';c=getchar())if(c=='-')fl=-fl;
    	while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
    	return fl==1?x:-x;
    }
    void iterate(int x,int l,int r){if(l==r)printf("%d ",seg[x].tag);else pushdown(X),iterate(LSON),iterate(RSON);}
    int main(){
    //	freopen("integer3.in","r",stdin);
    	n=read(),read(),read(),read();
    	build(1,0,n+10);
    //	iterate(1,0,n+10),puts("");
    	for(int i=1,tp,a,b;i<=n;i++){
    		tp=read(),a=read();
    		if(tp==1)b=read(),modify(a,b);
    		else printf("%d\n",query(a));
    //	iterate(1,0,n+10),puts("");
    	}
    	return 0;
    }
    

  • 相关阅读:
    Fortify Audit Workbench Cookie Security: Cookie not Sent Over SSL
    Fortify Audit Workbench 笔记 Access Control: Database
    MATLAB中的polyfit函数的使用方法
    编写python代码时出现SyntaxError: invalid character in identifier的解决方法
    Windows10安装MinGW-W64出现Cannot download repository.txt的一种解决方法
    使用IDM下载B站视频出现声音跟视频分离的一种解决方法
    简洁桌面(使用Windows自带的桌面整理功能)
    MATLAB标记图像中特殊的点
    解决python使用pip安装下载库出现错误:ERROR:Cannot unpack file xxxx情况
    解决python使用pip下载安装库速度慢问题
  • 原文地址:https://www.cnblogs.com/Troverld/p/14612772.html
Copyright © 2020-2023  润新知