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;
}
博主是蒟蒻,有问题请指出,谢谢!
本博客中博文均为原创,未经博主允许请勿随意转载,谢谢。
本博客中博文均为原创,未经博主允许请勿随意转载,谢谢。