写的时候一直没发现有一个问题
看了一遍kuangbin的代码,自己以为理解了,手写了一边,wa了
找了半天才发现 Query(o<<1|1,mid+1,r,mid+1) 不是Query(o<<1|1,mid+1,r) 位置是x
我选择x的话,会一直递归左子树 答案就是变成2了
实际答案是3
第一份代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=50005;
int n,m,x,v;
int sum[maxn*4],lsum[maxn*4],rsum[maxn*4];
int a[maxn];
int dq[maxn];
void Build(int o,int l,int r)
{
sum[o]=lsum[o]=rsum[o]=r-l+1;
if(l==r) {
return ;
}
int mid=l+r>>1;
Build(o<<1,l,mid);
Build(o<<1|1,mid+1,r);
}
void Update(int o,int l,int r)
{
if(l==r) {
lsum[o]=rsum[o]=sum[o]=v; return ;
}
int mid=l+r>>1;
if(x<=mid) {
Update(o<<1,l,mid);
}
else{
Update(o<<1|1,mid+1,r);
}
lsum[o]=lsum[o<<1];
rsum[o]=rsum[o<<1|1];
sum[o]=max(sum[o<<1],max(sum[o<<1|1],rsum[o<<1]+lsum[o<<1|1]));
if(lsum[o<<1]==mid-l+1) {
lsum[o]+=lsum[o<<1|1];
}
if(rsum[o<<1|1]==r-mid) {
rsum[o]+=rsum[o<<1];
}
}
int Query(int o,int l,int r,int x)
{
if(l==r||sum[o]==r-l+1||sum[o]==0) {
return sum[o];
}
int mid=l+r>>1;
if(x<=mid) {
if(x>=mid-rsum[o<<1]+1) {
return Query(o<<1,l,mid,x)+Query(o<<1|1,mid+1,r,mid+1);
}
else {
return Query(o<<1,l,mid,x);
}
}
else{
if(x<=mid+lsum[o<<1|1]) {
return Query(o<<1,l,mid,mid)+Query(o<<1|1,mid+1,r,x);
}
else{
return Query(o<<1|1,mid+1,r,x);
}
}
}
int main()
{
while(~scanf("%d%d",&n,&m)) {
Build(1,1,n);
char s[5];
int len=0;
while(m--) {
scanf("%s",s);
if(s[0]=='D') {
scanf("%d",&x); v=0;
Update(1,1,n); dq[len++]=x;
// printf("%d %d %d\n",sum[1],lsum[1],rsum[1]);
}
if(s[0]=='Q') {
scanf("%d",&x);
printf("%d\n",Query(1,1,n,x));
}
if(s[0]=='R') {
x=dq[--len]; v=1;
Update(1,1,n);
}
}
}
}
我自己又感觉麻烦,改了改那一点,代码如下
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=50005;
int n,m,x,v;
int sum[maxn*4],lsum[maxn*4],rsum[maxn*4];
int a[maxn];
int dq[maxn];
void Build(int o,int l,int r)
{
sum[o]=lsum[o]=rsum[o]=r-l+1;
if(l==r) {
return ;
}
int mid=l+r>>1;
Build(o<<1,l,mid);
Build(o<<1|1,mid+1,r);
}
void Update(int o,int l,int r)
{
if(l==r) {
lsum[o]=rsum[o]=sum[o]=v; return ;
}
int mid=l+r>>1;
if(x<=mid) {
Update(o<<1,l,mid);
}
else{
Update(o<<1|1,mid+1,r);
}
lsum[o]=lsum[o<<1];
rsum[o]=rsum[o<<1|1];
sum[o]=max(sum[o<<1],max(sum[o<<1|1],rsum[o<<1]+lsum[o<<1|1]));
if(lsum[o<<1]==mid-l+1) {
lsum[o]+=lsum[o<<1|1];
}
if(rsum[o<<1|1]==r-mid) {
rsum[o]+=rsum[o<<1];
}
}
int Query(int o,int l,int r,int x)
{
if(l==r||sum[o]==r-l+1||sum[o]==0) {
return sum[o];
}
int mid=l+r>>1;
if(x<=mid) {
if(x>=mid-rsum[o<<1]+1) {
return rsum[o<<1]+lsum[o<<1|1];
}
else {
return Query(o<<1,l,mid,x);
}
}
else{
if(x<=mid+lsum[o<<1|1]) {
return rsum[o<<1]+lsum[o<<1|1];
}
else{
return Query(o<<1|1,mid+1,r,x);
}
}
}
int main()
{
while(~scanf("%d%d",&n,&m)) {
Build(1,1,n);
char s[5];
int len=0;
while(m--) {
scanf("%s",s);
if(s[0]=='D') {
scanf("%d",&x); v=0;
Update(1,1,n); dq[len++]=x;
// printf("%d %d %d\n",sum[1],lsum[1],rsum[1]);
}
if(s[0]=='Q') {
scanf("%d",&x);
printf("%d\n",Query(1,1,n,x));
}
if(s[0]=='R') {
x=dq[--len]; v=1;
Update(1,1,n);
}
}
}
}