• bzoj 1012


    典型数据结构题,可用线段树、ST表、栈、树状数组。

    线段树就不说了,裸的一比,也不难打,就是跑得有点慢。

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    #define mid (l+r>>1)
    #define lc (o<<1)
    #define rc (o<<1)+1
    using namespace std;
    int read(){
        char c; while(!isdigit(c=getchar())); int x=c-'0';
        while(isdigit(c=getchar())) x=x*10+c-'0'; return x;
    }
    int cnt,t,maxv[1<<19];
    void change(int o,int l,int r,int w,int v){
        if(l>w || r<w) return;
        if(l==r){maxv[o]=v; return;}
        change(lc,l,mid,w,v);
        change(rc,mid+1,r,w,v);
        maxv[o]=max(maxv[lc],maxv[rc]);
    }
    int search(int o,int l,int r,int L,int R){
        if(l>R || r<L) return 0;
        if(l>=L && r<=R) return maxv[o];
        return max(search(lc,l,mid,L,R),search(rc,mid+1,r,L,R));
    }
    int main(){
        int m=read(),d=read();
        for(int i=1;i<=m;i+=1){
            char c; while(c=getchar(),c!='A' && c!='Q');
            if(c=='A') change(1,1,m,++cnt,((long long)read()+t)%d);
            else printf("%d\n",t=search(1,1,m,cnt-read()+1,cnt));
        }
        return 0;
    }

    ST表在网上貌似不多,这个数据结构是天生支持从末尾插入的。

    代码很短,就是内存需要得比较大,跑得还是挺快的。

    #include<cstdio>
    #include<cctype>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    int read(){
        char c; while(!isdigit(c=getchar())); int x=c-'0';
        while(isdigit(c=getchar())) x=x*10+c-'0'; return x;
    }
    int f[200001][19];
    int main(){
        int n=0,m=read(),d=read(),t=0;
        while(m--){
            char opt; while(opt=getchar(),opt!='A' && opt!='Q');
            if(opt=='A'){
                f[++n][0]=((long long)read()+t)%d;
                for(int i=1;(1<<i)<=n;i+=1)
                    f[n][i]=max(f[n-(1<<i-1)][i-1],f[n][i-1]);
            }else{
                int l=read(),x=log2(l);
                t=max(f[n-l+(1<<x)][x],f[n][x]);
                printf("%d\n",t);
            }
        }
        return 0;
    }

    由于询问一定是询问的最后几个中的最大值,所以我们可以维护单调性,保证栈顶到栈底单调递增。

    输出时二分一下可以取的在栈中位置最底下的那个元素。

    这是我写的这四个方法中跑得最快的一个,代码也很短。

    #include<cstdio>
    #include<cctype>
    int read(){
        char c; while(!isdigit(c=getchar())); int x=c-'0';
        while(isdigit(c=getchar())) x=x*10+c-'0'; return x;
    }
    int cnt,top,t,s[200001][2];
    int main(){
        int m=read(),d=read();
        while(m--){
            char c; while(c=getchar(),c!='A' && c!='Q');
            if(c=='A'){
                int x=((long long)read()+t)%d;
                while(top && s[top][0]<=x) top--;
                s[++top][0]=x; s[top][1]=++cnt;
            }else{
                int l=1,r=top,v=read();
                while(l<=r){
                    int mid=l+r>>1;
                    if(s[mid][1]>cnt-v) t=s[mid][0],r=mid-1; else l=mid+1;
                }
                printf("%d\n",t);
            }
        }
        return 0;
    }

    树状数组的做法貌似也不多。

    先统计有多少次增加元素。

    然后编号倒一下,第一个变成最后一个,以此类推。

    然后直接树状数组维护即可。

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    int read(){
        char c; while(!isdigit(c=getchar())); int x=c-'0';
        while(isdigit(c=getchar())) x=x*10+c-'0'; return x;
    }
    int tot,t,opt[200001],v[200001],tree[200001];
    int main(){
        int m=read(),d=read();
        for(int i=1;i<=m;i+=1){
            char c; while(c=getchar(),c!='A' && c!='Q');
            if(c=='A') opt[i]=1,tot++; else opt[i]=2;
            v[i]=read();
        }
        int now=tot+1;
        for(int i=1;i<=m;i+=1)
            if(opt[i]==1){
                int add=((long long)v[i]+t)%d;
                for(int j=--now;j<=tot;j+=j&-j) tree[j]=max(tree[j],add);
            }else{
                t=0;
                for(int j=now+v[i]-1;j>=now;j-=j&-j) t=max(tree[j],t);
                printf("%d\n",t);
            }
        return 0;
    }
  • 相关阅读:
    Python Xcode搭建Python环境以及使用PyCharm CE
    Python 集体智慧编程PDF
    Swift tableview自带的刷新控件
    iOS 类似朋友圈的图片浏览器SDPhotoBrowser
    程序员应掌握的算法
    C++ 知识点总结复习
    iOS 图片的拉伸,取固定区域显示
    iOS 获取一个不变的UDID
    iOS 应用中加载文档pdf/word/txt
    LeetCode-Design Snake Game
  • 原文地址:https://www.cnblogs.com/AmnesiacVisitor/p/7591583.html
Copyright © 2020-2023  润新知