【JSOI2008】【bzoj1012】最大數maxnumber

小哈里發表於2018-04-22

題面

維護一個數列,提供以下兩種操作:
1、 查詢操作:查詢當前數列中末尾L個數中的最大的數,並輸出這個數的值。
2、 插入操作:將n加上t,其中t是最近一次查詢操作的答案(如果還未執行過查詢操作,則t=0),並將所得結果對一個固定的常數D取模,將所得答案插入到數列的末尾。

題解

1、思路:維護一顆葉節點數為m的線段樹(就算m次操作都是插入也只有m個元素),區間查詢即可。複雜度O(mlog2m

m*log_2m
)。
2、資料有毒。。。bzojAC的code洛谷MLE,洛谷AC的bzojTLE。

BZOJAC[洛谷MLE,不知道為什麼]

//#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 200005;

int sgt[maxn<<2];
void change(int p, int l, int r, int x, int v){
    if(l == r){
        sgt[p] = v;
        return ;
    }
    int m = (l+r)/2;
    if(x <= m)change(p*2,l,m,x,v);
    if(x > m)change(p*2+1,m+1,r,x,v);
    sgt[p] = max(sgt[p*2],sgt[p*2+1]);
}
int query(int p, int l, int r, int L, int R){
    if(L <= l && r <= R)return sgt[p];
    int m = (l+r)/2, ans = 0;
    if(L <= m)ans = max(ans, query(p*2,l,m,L,R));
    if(R > m)ans = max(ans, query(p*2+1,m+1,r,L,R));
    return ans;
}

int main(){
    //ios::sync_with_stdio(false);
    int n=0, m, mod, t=0;
    scanf("%d %d",&m, &mod);//cin>>m>>mod;
    for(int i = 1; i <= m; i++){
        char op[2];  int x;  //cin>>op>>x;
        scanf("%s%d", op, &x);
        if(op[0] == 'Q'){
            printf("%d\n", t=query(1,1,m,n-x+1,n));
            //cout<<(t = query(1,1,m,n-x+1,n))<<"\n";
        }else{
            change(1,1,m,++n,(x+t)%mod);
        }
    }
    return 0;
}

luoguAC[bzojTLE,好像是scanf的鍋]

#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 200010;
typedef long long LL;

struct node{
    int l, r;
    LL val, addmark;
}sgt[maxn<<2];
void build(int p, int l, int r){
    sgt[p].l = l, sgt[p].r = r;
    if(l == r){
        //sgt[p].val = a[l];
    }else{
        int m = (l+r)/2;
        build(p*2,l,m);
        build(p*2+1,m+1,r);
        sgt[p].val = max(sgt[p*2].val,sgt[p*2+1].val);
    }
}
void change(int p, int x, int v){
    if(sgt[p].l == sgt[p].r){
        sgt[p].val = v;
        return ;
    }
    int m = (sgt[p].l+sgt[p].r)/2;
    if(x <= m)change(p*2,x,v);
    if(x > m)change(p*2+1,x,v);
    sgt[p].val = max(sgt[p*2].val,sgt[p*2+1].val);
}
LL query(int p, int l, int r){
    if(l <= sgt[p].l && sgt[p].r <= r)return sgt[p].val;
    LL m = (sgt[p].l+sgt[p].r)/2, ans = 0;
    if(l <= m)ans = max(ans, query(p*2,l,r));
    if(r > m)ans = max(ans, query(p*2+1,l,r));
    return ans;
}

int main(){
    ios::sync_with_stdio(false);
    LL n=0, m, mod, t=0;
    cin>>m>>mod;
    build(1,1,m);
    for(int i = 1; i <= m; i++){
        char op;  LL x;  cin>>op>>x;
        if(op == 'Q'){
            cout<<(t = query(1,n-x+1,n))<<"\n";
        }else{
            change(1,++n,(x+t)%mod);
        }
    }
    return 0;
}

相關文章