zoukankan      html  css  js  c++  java
  • 洛谷P1198 [JSOI2008]最大数

    洛谷P1198 [JSOI2008]最大数

    题目描述

    现在请求你维护一个数列,要求提供以下两种操作:

    1、 查询操作。

    语法:Q L

    功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。

    限制:L不超过当前数列的长度。

    2、 插入操作。

    语法:A n

    功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾。

    限制:n是整数(可能为负数)并且在长整范围内。

    注意:初始时数列是空的,没有一个数。

    输入输出格式

    输入格式:

    第一行两个整数,M和D,其中M表示操作的个数(M <= 200,000),D如上文中所述,满足(0<D<2,000,000,000)

    接下来的M行,每行一个字符串,描述一个具体的操作。语法如上文所述。

    输出格式:

    对于每一个查询操作,你应该按照顺序依次输出结果,每个结果占一行。

    输入输出样例

    输入样例#1: 复制
    5 100
    A 96
    Q 1
    A 97
    Q 1
    Q 2
    
    输出样例#1: 复制
    96
    93
    96
    

    说明

    [JSOI2008]

     

    分析

    由于插入的元素最多m个所以可以让一开始的队尾是m然后记录队首,由于假如是倒着加的,所以用树状数组查询前缀和就可以了。

    但是这题还可以用单调栈+二分来做。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    int m,d,num,t;
    int c[200000+5];
    inline void update(int x,int d)
    {
        while(x<=m)
        {
            c[x]=max(c[x],d);
            x+=x&(-x);
        }
    }
    inline int query(int x)
    {
        int res=-2000000000;
        while(x)
        {
            res=max(res,c[x]);
            x-=x&(-x);
        }
        return res;
    }
    int main()
    {
        memset(c,-0x3f,sizeof(c));
        m=read(); d=read();
        num=m;
        for(int i=1;i<=m;i++)
        {
            char tmp[3]; int k;
            scanf("%s",tmp);  k=read();
            if(tmp[0]=='A')
            {
                update(num,(k+t)%d);
                num--;
            }
            if(tmp[0]=='Q')
            {
                t=query(num+k);
                printf("%d
    ",t);
            }
        }
        return 0;
    }
    树状数组
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=200010;
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,p,t,top,cnt;
    int num[N],sta[N];
    int main(){
        n=read();p=read();
        char ch[3];
        for(int i=1;i<=n;++i){
            scanf("%s",ch); int x=read();
            if(ch[0]=='A'){
                ++cnt;
                x=(x+t)%p;
                while(top&&x>=sta[top]) --top;
                sta[++top]=x; num[top]=cnt;
            }else if(ch[0]=='Q'){
                int l=1,r=top,mid;
                x=cnt-x+1;
                while(l<=r){
                    mid=(l+r)>>1;
                    if(num[mid]<x) l=mid+1;
                    else r=mid-1;
                }
                t=sta[l];
                printf("%d
    ",t);
            }
        }
        return 0;
    }
    单调栈+二分
  • 相关阅读:
    Anagram
    HDU 1205 吃糖果(鸽巢原理)
    Codeforces 1243D 0-1 MST(补图的连通图数量)
    Codeforces 1243C Tile Painting(素数)
    Codeforces 1243B2 Character Swap (Hard Version)
    Codeforces 1243B1 Character Swap (Easy Version)
    Codeforces 1243A Maximum Square
    Codeforces 1272E Nearest Opposite Parity(BFS)
    Codeforces 1272D Remove One Element
    Codeforces 1272C Yet Another Broken Keyboard
  • 原文地址:https://www.cnblogs.com/huihao/p/7791481.html
Copyright © 2011-2022 走看看