bzoj1012 [JSOI2008]最大数maxnumber

bzoj1012 [JSOI2008]最大数maxnumber


这是一道线段树裸题。
rt

#include<iostream>
#include<cstdio>
#include<cstdlib>
#define N 200000
#define max(a,b) ((a>b)?(a):(b))
using namespace std;
typedef long long ll;
ll L[4*N+1],R[4*N+1];
ll d,m;
ll a[4*N+1];
inline ll gi() {
	ll p=0;
	char c=getchar();
	while(c<'0'||c>'9')c=getchar();
	while(c>='0'&&c<='9')p=p*10+c-'0',c=getchar();
	return p;
}
inline void build(int o,ll l,ll r) {
	L[o]=l;R[o]=r;
	if(l==r)return;
	build(o<<1,l,(l+r)>>1);
	build(o<<1|1,((l+r)>>1)+1,r);
}
inline void update(int o,ll i,ll n) {
	if(L[o]==R[o]){a[o]=n;return;}
	ll mid=(L[o]+R[o])>>1;
	if(i<=mid)update(o<<1,i,n);
	else update(o<<1|1,i,n);
	a[o]=max(a[o<<1],a[o<<1|1]);
}
inline ll maxx(int o) {
	if(L[o]>=L[0]&&R[o]<=R[0])return a[o];
	ll mid=(L[o]+R[o])>>1;
	if(mid>=L[0])
		if(mid<R[0])return max(maxx(o<<1),maxx(o<<1|1));
		else return maxx(o<<1);
	else return maxx(o<<1|1);
}
int main() {
	m=gi();d=gi();
	build(1,1,m);
	ll t=0,a,nowsize=0;
	char h;
	while(m--) {
		h='0';
		while(h!='A'&&h!='Q')h=getchar();
		a=gi();
		if(h=='A')update(1,++nowsize,(t+a)%d);
		else{L[0]=nowsize-a+1;R[0]=nowsize;printf("%lld\n",t=maxx(1));}
	}
	return 0;
}

cjoj 549ms


末尾操作,这题用二分+单调栈也能做哈(fread大法好)cjoj 86ms

// It is made by XZZ
#include<cstdio>
#include<algorithm>
using namespace std;
#define rep(a,b,c) for(rg int a=b;a<=c;a++)
#define drep(a,b,c) for(rg int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define vd void
typedef long long ll;
il char gc(){
    const int B=65535;static char b[65539],*p=b+B;
    if(p==b+B)b[fread(b,1,B,stdin)]=0,p=b;
    return *p?*p++:0;
}
il ll gi(){
    rg ll x=0;rg bool flg=0;rg char ch=gc();
    while(ch<'0'||ch>'9'){if(ch=='-')flg=1;ch=gc();}
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=gc();
    return flg?-x:x;
}
const int maxn=200010;
ll stk[maxn],rt[maxn];
char opt;
int main(){
    ll m=gi(),x,lst=0,D=gi(),l,r,k,s=0,top=0;
    while(m--){
    do opt=gc();while((opt^'A')&&(opt^'Q'));
    x=gi();
    if(opt=='A'){
        x+=lst,x%=D;
        while(top&&stk[top]<=x)--top;
        stk[++top]=x,rt[top]=++s;
    }else{
        l=1,r=top,k=s-x+1;
        while(l<r)
        if(rt[(l+r)>>1]<k)l=((l+r)>>1)+1;
        else r=(l+r)>>1;
        printf("%lld\n",lst=stk[l]);
    }
    }
    return 0;
}
posted @ 2017-09-28 09:10  菜狗xzz  阅读(179)  评论(0编辑  收藏  举报