zoukankan      html  css  js  c++  java
  • B1012 [JSOI2008]最大数maxnumber 分块||RMQ

    这个题有毒,卡最大值。。。我开1 << 30爆零让我以为我分块错了。。。gg,然后去写RMQ,但是这个题st表是真简单啊。后来刘胜与巨佬一眼看出来我最大值不够大。。。然后1LL<<60也爆零,然而1 << 60 AC,(60LL)AC,1e8爆零。。。无良数据。。。

    题目:

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

    分块代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(int i = a;i <= n;i++)
    #define lv(i,a,n) for(int i = a;i >= n;i--)
    #define clean(a) memset(a,0,sizeof(a))
    const long long INF = (60LL);
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    int bl,n,m,d,len = 0;
    ll k[200005];
    ll a[200005];
    char s[5];
    int main()
    {
        read(m);read(d);
        bl = sqrt(m);
        int t = 0,l = 1;
        duke(i,1,m)
        {
            ll x;
            scanf("%s%lld",s,&x);
            if(s[0] == 'Q')
            {
                n = len - x + 1;
                if(n > (len / bl - 1) * bl)
                {
                    ll maxn = 0;
                    duke(i,n,len)
                    {
                        if(maxn < a[i])
                        maxn = a[i];
                    }
                    printf("%lld
    ",maxn);
                    t = maxn;
                }
                else
                {
                    ll maxn = 0;
                    duke(i,n / bl + 2,len / bl)
                    {
                        if(maxn < k[i])
                        maxn = k[i];
                    }
                    duke(i,l,len)
                    {
                        if(maxn < a[i])
                        maxn = a[i];
                    }
                    duke(i,n,(n / bl + 1) * bl)
                    {
                        if(maxn < a[i])
                        maxn = a[i];
                    }
                    t = maxn;
                    printf("%lld
    ",maxn);
                }
            }
            else
            {
                x += t;
                if(x < 0)
                x += d;
                x %= d;
                a[++len] = x;
                if(len % bl == 0)
                {
                    ll maxn = INF;
                    duke(i,l,len)
                    {
                        if(maxn < a[i])
                        maxn = a[i];
                    }
                    k[len / bl] = maxn;
                    l = len + 1;
                }
            }
        }
    }
    /*
    9 100
    A 1
    A 2
    A 3
    A 4
    A 5
    Q 3
    A 7
    A 8
    Q 4
    */
    /*
    5 100
    A 96
    Q 1
    A 97
    Q 1
    Q 2
    */

    RMQ代码:

    #include <cstdio>
    #include <cmath>
    #include <iostream>
    #include <cstring>
    #define ll long long
    using namespace std;
    ll a[200001],f[200001][21],t,D;
    int n,m;
    bool flag;
    void change(int u)   //用change函数来进行修改
    {
        f[u][0]=a[u];
        for(int i=1; u-(1<<i)>=0; i++) f[u][i]=max(f[u][i-1],f[u-(1<<(i-1))][i-1]);
    }
    ll find(int x,int y)
    {
        double t=log(y-x+1)/log(2);
        int K=t;
        return max(f[y][K],f[x+(1<<K)-1][K]);
    }
    int main()
    {
        memset(f,0,sizeof(f));
        scanf("%d%lld",&m,&D);
        for (int i=1; i<=m; i++)
        {
            char c;
            cin>>c;
            ll x;
            if (c=='A')   //根据题面的操作,注意细节。
            {
                scanf("%lld",&x);
                a[++n]=(x+t)%D;
                change(n);
            }
            else
            {
                int L;
                scanf("%d",&L);
                ll ans;
                if (L==1)
                {
                    printf("%lld
    ",a[n]);
                    t=a[n];
                    continue;
                }
                ans=find(n-L+1,n);
                printf("%lld
    ",ans);
                t=ans;
            }
        }
        return 0;
    }
  • 相关阅读:
    github上传文件让别人下载--xdd
    C#Windows Forms 使MessageBox顶层显示--xdd
    2019.7.16.5.21留念
    Fortran流程控制与逻辑运算、循环--xdd
    Fortran输入输出与声明--xdd
    c#关于数据和方法在不同类中的引用-xdd
    C#Windows Forms (Demo.SYS)--xdd
    github下载历史版本--xdd
    Matlab查看本机IP地址---xdd
    Matlab生成Word--xdd
  • 原文地址:https://www.cnblogs.com/DukeLv/p/9544364.html
Copyright © 2011-2022 走看看