zoukankan      html  css  js  c++  java
  • [BZOJ] 1012 [JSOI2008]最大数maxnumber

    Time Limit: 3 Sec  Memory Limit: 162 MB
    Submit: 13224  Solved: 5728
    [Submit][Status][Discuss]
    Description
      现在请求你维护一个数列,要求提供以下两种操作:1、 查询操作。语法:Q L 功能:查询当前数列中末尾L
    个数中的最大的数,并输出这个数的值。限制:L不超过当前数列的长度。2、 插入操作。语法:A n 功能:将n加
    上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取
    模,将所得答案插入到数列的末尾。限制:n是非负整数并且在长整范围内。注意:初始时数列是空的,没有一个
    数。
    
    Input
      第一行两个整数,M和D,其中M表示操作的个数(M <= 200,000),D如上文中所述,满足Dlongint内。接下来
    M行,查询操作或者插入操作。
    
    Output
      对于每一个询问操作,输出一行。该行只有一个数,即序列中最后L个数的最大数。
    
    Sample Input
    5 100
    
    A 96
    
    Q 1
    
    A 97
    
    Q 1
    
    Q 2
    Sample Output
    96
    
    93
    
    96

    分块大力搞,luogu最后一个点会T。

    /**************************************************************
        Problem: 1012
        User: GhostCai
        Language: C++
        Result: Accepted
        Time:908 ms
        Memory:7476 kb
    ****************************************************************/
    
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #define R register
    #define max(a,b) (a>b?a:b)
    #define min(a,b) (a<b?a:b)
    typedef long long ll;
    
    inline ll rd(){
        ll ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    
    const int MAXB=1024<<1;
    const int MAXN=262144<<1;
    int l[MAXB],r[MAXB],belong[MAXN];
    ll mx[MAXB];
    int block,num;
    int mod,n;
    
    inline void build(){
        block=sqrt(n)/2;
        num=n/block;
        if(n%block) num++;
        for(R int i=1;i<=num;i++){
            l[i]=(i-1)*block+1;
            r[i]=i*block;
        }
        for(R int i=1;i<=n;i++) belong[i]=(i-1)/block+1;
    }
    
    int cnt;
    ll a[MAXN];
    
    inline void updata(ll x){
        a[++cnt]=x;
        mx[belong[cnt]]=max(mx[belong[cnt]],x);
    }
    
    inline int query(ll x){
        int p=cnt-x+1;
        ll ret=0;
        if(belong[p]==belong[cnt]){
            for(R int i=p;i<=cnt;i++) ret=max(ret,a[i]);
            return ret;
        }
        for(R int i=p;i<=r[belong[p]];i++) ret=max(ret,a[i]);
        for(R int i=belong[p]+1;i<belong[cnt];i++) ret=max(ret,mx[i]);
        for(R int i=l[belong[cnt]];i<=cnt;i++) ret=max(ret,a[i]);
        return ret;
    }
    
    int main(){
        n=rd();mod=rd();
        build();
        char s[5];ll x,t=0;
        for(R int i=1;i<=n;i++){
            scanf("%s",s);
            x=rd();
            if(s[0]=='A'){
                x+=t;
                while(x<0) x+=mod;
    //          cout<<"UPDATA:"<<x<<endl;
                updata(x%mod);
            }else{
                t=query(x);
                printf("%lld
    ",t);
            }
        }
        return 0;
    }

    线段树,长时间不写生疏了,感觉不太好

    #include<iostream>
    #include<cstdio>
    
    using namespace std;
    
    const long long MAXN=4000005;
    
    inline long long rd() {
        long long ret=0,f=1;
        char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    
    struct Seg{
        #define ls (now<<1)
        #define rs ((now<<1)+1)
        long long mx[MAXN];
        void pushup(long long now){mx[now]=max(mx[ls],mx[rs]);}
        void updata(long long now,long long L,long long R,long long l,long long r,long long w){
            if(L<=l&&r<=R) {mx[now]=w;return;}
            long long mid=(l+r)>>1;
            if(L<=mid) updata(ls,L,R,l,mid,w);
            if(mid <R) updata(rs,L,R,mid+1,r,w);
            pushup(now);
        }
        long long query(long long now,long long L,long long R,long long l,long long r){
            if(L<=l&&r<=R) return mx[now];
    
    
            long long mid=(l+r)>>1,ret=0;
            if(L<=mid) ret=max(ret,query(ls,L,R,l,mid));
            if(mid <R) ret=max(ret,query(rs,L,R,mid+1,r));
            return ret;
        }       
    }seg;
    
    long long p;
    long long m,mod;
    
    signed main(){
        m=rd();mod=rd();
        char s[5];long long x,t=0;
        for(long long i=1;i<=m;i++){
            scanf("%s",s);x=rd();
            if(s[0]=='Q') {
                t=seg.query(1,p-x+1,p,1,200000);
                t%=mod;
                printf("%d
    ",t);
            }
            else ++p,seg.updata(1,p,p,1,200000,(x+t)%mod);
        }
        return 0;
    }

    常数最小的方法,新科技,动态ST表,适用于只往后插入的。
    f[i][j]为i往前(1 << j)的最大值,假设已经维护好了前i-1位,那么新加入一位不会对前面造成影响,可以在O(logn)的时间完成更新。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    
    const int MAXN=200005;
    
    typedef long long ll;
    
    inline ll rd(){
        ll ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    ll f[MAXN][32];
    ll m,mod;
    int p;
    
    int main(){
        m=rd();mod=rd();
        char s[5];ll x,t=0;
        while(m--){
            scanf("%s",s);x=rd();
            if(s[0]=='Q') {
                int len=log2(x);
                printf("%lld
    ",t=max(f[p][len],f[p-x+(1<<len)][len])%mod);
            }else{
                f[++p][0]=(x+t)%mod;
                for(int i=1;p-(1<<i)>=0;i++) f[p][i]=max(f[p][i-1],f[p-(1<<(i-1))][i-1]);
            }
        }
        return 0;
    }

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9247386.html

  • 相关阅读:
    zabbix4.0版本(四)
    《柯尔特思维教程》-第4章(创造力)- 第9节:要求
    《柯尔特思维教程》-第4章(创造力)- 第8节:合并
    《柯尔特思维教程》-第4章(创造力)- 第7节:去掉缺点
    《柯尔特思维教程》-第4章(创造力)- 第6节:定义问题
    《柯尔特思维教程》-第4章(创造力)- 第5节:主要观点
    《柯尔特思维教程》-第4章(创造力)- 第4节:挑战概念
    《柯尔特思维教程》-第4章(创造力)- 第3节:随意输入
    《柯尔特思维教程》-第4章(创造力)- 第2节:跳板
    《柯尔特思维教程》-第4章(创造力)- 第1节:YES、NO和PO
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9247386.html
Copyright © 2011-2022 走看看