• 洛谷 P1198 [JSOI2008]最大数


    现在请求你维护一个数列(初始数列为空),要求提供以下两种操作:

    1、 查询操作。

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

    2、 插入操作。

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

    如何每一次在末尾插入一个数并维护最大值

    因为一共有\(M\)次操作,所以最多也只有可能\(M\)个数,那么当插入第\(Q\)个数时我们就把它放在第\(Q\)个位置,这样子就解决了插入操作。

    查询也是很简单的,之前我们把每个数放在了末尾,现在放在了前面,所以每次只要查询从最后一个有数的位置往前\(L\)个位置,也就是\([Q-L+1,Q]\)

    这样这道题就变成了一道单点修改区间和的板子题辣~!

    完整代码

    #include <iostream>
    using namespace std;
    char ch;
    int ma[8000001],ad[8000001],m,d,t,q,n;
    int build(int k,int l,int r)
    {
        if (l==r)
        {
            ma[k]=0;
            return 0;
        }
        int mid=l+r>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
    }
    int insert(int k,int l,int r,int x,int v)
    {
        if (l==r)return ma[k]=v;
        int mid=l+r>>1;
        if (x<=mid)insert(k<<1,l,mid,x,v);
        else insert(k<<1|1,mid+1,r,x,v);
        ma[k]=max(ma[k<<1],ma[k<<1|1]);
    }
    int que(int k,int l,int r,int x,int y)
    {
        if (l>=x&&r<=y)return ma[k];
        int mid=l+r>>1,ans=0;
        if (x<=mid)ans=max(ans,que(k<<1,l,mid,x,y));
        if (y>mid)ans=max(ans,que(k<<1|1,mid+1,r,x,y));
        ma[k]=max(ma[k<<1],ma[k<<1|1]);
        return ans;
    }
    int main()
    {
        cin>>m>>d;
        int a1;
        n=m;
        //build(1,1,n);
        for (int i=1;i<=m;i++)
        {
            cin>>ch>>a1;
            if (ch=='A')
            {
                q++;
                insert(1,1,n,q,(a1+t)%d);
            }
            else
            {
                t=que(1,1,n,q-a1+1,q);
                cout<<t<<endl;
            }
        }
        return 0;
    } 
    

    代码丑见谅qwq

  • 相关阅读:
    第五周作业
    第四周作业
    第三周作业
    第二周作业
    第一周作业
    FileZilla连接centos7失败处理(SSH)
    单例设计模式
    JQuery中的$符号的作用----网摘
    浅谈关于“中文编程”是否会成为中国程序员的一颗“银弹”
    第8周作业 邱鹏 2013551628
  • 原文地址:https://www.cnblogs.com/sdlang/p/13068061.html
Copyright © 2020-2023  润新知