被我xjb二分卡过去了
ACcode;
#include <cstdio>
#include <cstring>
#define tmp (st<<1)
#define mid ((l+r)>>1)
#define lson l,mid,tmp
#define rson mid+1,r,tmp|1
#define maxn 50002
#define len (r-l+1)
#define push_up(x) sum[x]=sum[tmp]+sum[tmp|1]
using namespace std;
int sum[maxn<<2],sta[maxn],top;
inline void build(int l,int r,int st){
if(l==r){
sum[st]=1;
return ;
}
build(lson);
build(rson);
push_up(st);
}
inline void updata(int t,int add,int l,int r,int st){
if(l==r){
sum[st]=add;
return ;
}
if(t<=mid)updata(t,add,lson);
else updata(t,add,rson);
push_up(st);
}
inline int query(int L,int R,int l,int r,int st){
if(L<=l&&r<=R)return sum[st];
int ret=0;
if(L<=mid)ret+=query(L,R,lson);
if(R>mid)ret+=query(L,R,rson);
return ret;
}
int main(){
int n,q,x;
char str[4];
while(~scanf("%d%d",&n,&q)){
build(1,n,1);
top=0;
while(q--){
scanf("%s",str);
if(str[0]=='D'){
scanf("%d",&x);
updata(x,0,1,n,1);
sta[++top]=x;
}
else if(str[0]=='R'&&top){
x=sta[top--];
updata(x,1,1,n,1);
}
else if(str[0]=='Q'){
scanf("%d",&x);
int ans=query(x,x,1,n,1);
if(ans==0){
printf("0\n");
continue;
}
int l=1,r=x-1,t,k=0;
while(l<=r){
t=query(mid,x-1,1,n,1);
if(t==x-mid){
k=x-mid;
r=mid-1;
}else l=mid+1;
}
ans+=k;
l=x+1,r=n,k=0;
while(l<=r){
t=query(x+1,mid,1,n,1);
if(t==mid-x){
k=mid-x;
l=mid+1;
}else r=mid-1;
}
ans+=k;
printf("%d\n",ans);
}
}
}
return 0;
}
花了一下午学了下区间合并
对于这道题来说查询到t的位置的时候要考虑t~mid或mid~t是否连续如果是的话需要查询连续的那一块
ACcode:
#include <cstdio>
#include <algorithm>
#include <cstring>
#define tmp (st<<1)
#define mid ((l+r)>>1)
#define lson l,mid,tmp
#define rson mid+1,r,tmp|1
#define maxn 50002
#define len (r-l+1)
using namespace std;
int sum[maxn<<2],sta[maxn],top,lsum[maxn<<2],rsum[maxn<<2];
inline void push_up(int st,int m){
lsum[st]=lsum[tmp];
rsum[st]=rsum[tmp|1];
sum[st]=max(max(sum[tmp],sum[tmp|1]),lsum[tmp|1]+rsum[tmp]);
if(lsum[st]==m-(m>>1))lsum[st]+=lsum[tmp|1];
if(rsum[st]==m>>1)rsum[st]+=rsum[tmp];
}
inline void build(int l,int r,int st){
sum[st]=lsum[st]=rsum[st]=len;
if(l==r)return ;
build(lson);
build(rson);
}
inline void updata(int t,int add,int l,int r,int st){
if(l==r){
sum[st]=lsum[st]=rsum[st]=add;
return ;
}
if(t<=mid)updata(t,add,lson);
else updata(t,add,rson);
push_up(st,len);
}
inline int query(int t,int l,int r,int st){
if(l==r||sum[st]==0||sum[st]==len) return sum[st];
if(t<=mid){
if(t>=mid-rsum[tmp]+1)///如果t到mid连续要查询mid右边
return query(t,lson)+query(mid+1,rson);
else
return query(t,lson);
}
else {
if(t<=mid+1+lsum[tmp|1]-1 )///同理
return query(t,rson)+query(mid,lson);
else
return query(t,rson);
}
}
int main(){
int n,q,x;
char str[4];
while(~scanf("%d%d",&n,&q)){
build(1,n,1);
top=0;
while(q--){
scanf("%s",str);
if(str[0]=='D'){
scanf("%d",&x);
updata(x,0,1,n,1);
sta[++top]=x;
}
else if(str[0]=='R'&&top){
x=sta[top--];
updata(x,1,1,n,1);
}
else if(str[0]=='Q'){
scanf("%d",&x);
printf("%d\n",query(x,1,n,1));
}
}
}
return 0;
}