• noi 2017 整数


      (可怕的是noi2017 6道黑题 这觉对是神仙 瞄了一眼 可能就这个整数可以写。

    这题是想让我们维护一个高精度的二进制数 且支持加法和减法以及第k位的查询。

    对于第k位的查询我们显然是直接把这个数字变成二进制数 然后直接 查询输出答案。

    至于加法和减法 观察 加上和减去这个数字 a*2^b 我们 把a进行二进制拆分 利用乘法分配律显然可以得到其实这个就是把这个a 在二进制的情况下左移b位。

    每一位在x对应的二进制数下加减就好了。但是不难发现 有进位和退位这个东西的。

    进位和退位显然是对一整个连续0 或者连续1 的区间作为修改。

    当然 有部分分是 所有修改都在询问之后 这样的话我们单单只进行单点修改就好了,最后再统一进行处理。(这个很好处理的

    这样的话 我们有一个比较显然的思路是 用线段树来维护这个过程 有了线段树的话 对于一段连续的修改 我们可以打上懒标记。

    而查找到应该修改的区间的话连续的0 可以用 | 这个操作来搞 连续的1 可以用& 这个操作搞定来快速锁定所要修改的区间。

    做到这里我们应该能得到了 13*4==72分的垃圾成绩而且还不好码。

    因为考虑到这个数字有多大 a->30位数字 b->30n n<=1000000 那么这整个数字就是 9*10^8这么多的数位 全挂到线段树上早就爆了。

    考虑压位操作 事实上我们是动态开点线段树 真实数位是 nlogn^2当然 这也足够大了也是9*10^8 

    考虑压位 我们直接30个二进制位为一个点 那么此时每次修改最多两个位置 n*2*logn ->240多MB 哇能过。

    那么此时考虑查找第k位那就/30 在这个节点中找k%30这一位的数字!

    修改呢 就是对应的位置直接相减,不够的话向前面借就好了,进位的话向前面进就好了。

    当然 我们需要维护区间是否全为2^30-1 或 0 .

    //#include<bits/stdc++.h>
    #include<iomanip>
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<queue>
    #include<deque>
    #include<cmath>
    #include<ctime>
    #include<cstdlib>
    #include<stack>
    #include<algorithm>
    #include<vector>
    #include<cctype>
    #include<utility>
    #include<set>
    #include<bitset>
    #include<map>
    #define INF 1000000000
    #define ll long long
    #define min(x,y) ((x)>(y)?(y):(x))
    #define max(x,y) ((x)>(y)?(x):(y))
    #define RI register ll
    #define db double
    #define EPS 1e-8
    #define s1(p) t[p].s1
    #define s2(p) t[p].s2
    #define tag(p) t[p].tag
    using namespace std;
    char buf[1<<15],*fs,*ft;
    inline char getc()
    {
        return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
    }
    inline int read()
    {
        int x=0,f=1;char ch=getc();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
        return x*f;
    }
    const int MAXN=1000010;
    int n,t1,t2,t3,root,num;
    ll d,mod,inf=(1<<30)-1;
    struct wy
    {
        int s1,s2;
        int tag;
        wy(){tag=-1;}
    }t[MAXN<<2];
    inline void pushdown(int p)
    {
        s1(p<<1)=s2(p<<1)=tag(p);
        s1(p<<1|1)=s2(p<<1|1)=tag(p);
        tag(p<<1)=tag(p<<1|1)=tag(p);
        tag(p)=-1;return;
    }
    inline void pushup(int p)
    {
        s1(p)=s1(p<<1)&s1(p<<1|1);
        s2(p)=s2(p<<1)|s2(p<<1|1);
        return;
    }
    inline int ask(int p,int l,int r,int x)
    {
        if(l==r)return s1(p);
        int mid=(l+r)>>1;
        if(tag(p)!=-1)pushdown(p);
        pushup(p);
        if(x<=mid)return ask(p<<1,l,mid,x);
        return ask(p<<1|1,mid+1,r,x);
    }
    inline void change(int p,int l,int r,int x,int k)
    {
        if(l==r){s1(p)+=k;s2(p)+=k;return;}
        int mid=(l+r)>>1;
        if(tag(p)!=-1)pushdown(p);
        if(x<=mid)change(p<<1,l,mid,x,k);
        else change(p<<1|1,mid+1,r,x,k);
        pushup(p);return;
    }
    inline int calculate(int p,int l,int r,int x,int k)
    {
        if(k==inf){if(s1(p)==k)return 0;}
        else if(s2(p)==k)return 0;
        if(l==r)return l;
        int mid=(l+r)>>1;
        if(tag(p)!=-1)pushdown(p);
        pushup(p);
        if(x<=mid)
        {
            int ans=calculate(p<<1,l,mid,x,k);
            return ans?ans:calculate(p<<1|1,mid+1,r,x,k);
        }
        return calculate(p<<1|1,mid+1,r,x,k);
    }
    inline void modify(int p,int l,int r,int L,int R,int k)
    {
        if(L<=l&&R>=r)
        {
            s1(p)=s2(p)=tag(p)=k;
            return;
        }
        int mid=(l+r)>>1;
        if(tag(p)!=-1)pushdown(p);
        if(L<=mid)modify(p<<1,l,mid,L,R,k);
        if(R>mid)modify(p<<1|1,mid+1,r,L,R,k);
        pushup(p);return;
    }
    inline void add(int x,int y)
    {
        int sum=ask(1,1,num,x);
        //cout<<x<<' '<<y<<endl;
        if(sum+y<=inf)change(1,1,num,x,y);
        else
        {
            change(1,1,num,x,y-inf-1);
            int w=calculate(1,1,num,x+1,inf);
            if(w!=x+1)modify(1,1,num,x+1,w-1,0);
            change(1,1,num,w,1);
        }
    }
    inline void SBT(int x,int y)
    {
        int sum=ask(1,1,num,x);
        if(sum>=y)change(1,1,num,x,-y);
        else
        {
            change(1,1,num,x,inf+1-y);
            int w=calculate(1,1,num,x+1,0);
            if(w!=x+1)modify(1,1,num,x+1,w-1,inf);
            change(1,1,num,w,-1);
        }
    }
    int main()
    {
        freopen("1.in","r",stdin);
        freopen("1.out","w",stdout);
        n=read();t1=read();t2=read();t3=read();
        num=n+2;
        for(int i=1;i<=n;++i)
        {
            ll p,a,b;
            p=read();
            switch(p)
            {
                case 1:
                a=read();b=read();
                d=b/30;mod=b%30;
                if(a>0)
                {
                    add(d+1,(a<<mod)&inf);
                    if(mod)add(d+2,((a<<mod)-((a<<mod)&inf))>>30);
                }
                else
                {
                    a=-a;
                    SBT(d+1,(a<<mod)&inf);//subtraction 减法 reduce 减少
                    if(mod)SBT(d+2,((a<<mod)-((a<<mod)&inf))>>30);
                }
                break;
                case 2:
                a=read()+1;d=a/30;mod=a%30;
                if(!mod)
                {
                    int sum=ask(1,1,num,d);
                    printf("%d
    ",sum>>29);
                    break;
                }
                int sum=ask(1,1,num,d+1);
                //cout<<sum<<endl;
                printf("%d
    ",(sum>>(mod-1))&1);
                break;
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    论文阅读 | MobileNetV2: Inverted Residuals and Linear Bottlenecks
    论文阅读 | MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications
    ResNet代码实现
    第二次作业:卷积神经网络 part 1
    第一次作业:深度学习基础
    对于当下和未来的一点点思考
    第六周:生成式对抗网络
    第五周:卷积神经网络 part3
    HybridSN 高光谱分类网络的优化
    第四周:卷积神经网络 part3
  • 原文地址:https://www.cnblogs.com/chdy/p/11288020.html
Copyright © 2020-2023  润新知