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\n",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\n",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\n",a[n]);
                t=a[n];
                continue;
            }
            ans=find(n-L+1,n);
            printf("%lld\n",ans);
            t=ans;
        }
    }
    return 0;
}

 

posted @ 2018-08-27 19:49  DukeLv  阅读(185)  评论(0编辑  收藏  举报