这个是错误代码
#include<cstdio>
#define maxn 100005
#define lid (k<<1)
#define rid (k<<1|1)
using namespace std;
struct node
{
int l,r;
int cnt0,cnt1;//记录0和1的数量
int fl;//lazy标记
}tr[maxn*4];
int n,m,q;
int a[maxn],lq[maxn],rq[maxn],op[maxn];
void update(int k)
{
tr[k].cnt0=tr[lid].cnt0+tr[rid].cnt0;
tr[k].cnt1=tr[lid].cnt1+tr[rid].cnt1;
}
void pushdown(int k)
{
int l=tr[k].l,r=tr[k].r;
int mid=(l+r)>>1;
if(tr[k].fl==0)
{
tr[lid].cnt0=mid-l+1;
tr[lid].cnt1=0;
tr[rid].cnt0=r-mid;
tr[rid].cnt1=0;
tr[lid].fl=tr[rid].fl=0;
}
else
{
tr[lid].cnt0=0;
tr[lid].cnt1=mid-l+1;
tr[rid].cnt0=0;
tr[rid].cnt1=r-mid;
tr[lid].fl=tr[rid].fl=1;
}
tr[k].fl=-1;
}
void build(int k,int l,int r,int val)
{
tr[k].l=l;
tr[k].r=r;
tr[k].fl=-1;
if(l==r)
{
tr[k].cnt0=tr[k].cnt1=0;
if(a[l]>=val)tr[k].cnt1=1;
else tr[k].cnt0=1;
// printf("%d ",tr[k].cnt1);
return;
}
int mid=(l+r)>>1;
build(lid,l,mid,val);
build(rid,mid+1,r,val);
update(k);
}//将大于mid的值赋为1,小于mid的值赋为0
void modify(int k,int l,int r,int c0,int c1,int opt)
{
if(tr[k].l>=l&&tr[k].r<=r)
{
if(!opt)
{
if(tr[k].r<=l+c0-1)
{
tr[k].cnt0=tr[k].r-tr[k].l+1;
tr[k].cnt1=0;
tr[k].fl=0;
}
else if(tr[k].l>=l+c0)
{
tr[k].cnt0=0;
tr[k].cnt1=tr[k].r-tr[k].l+1;
tr[k].fl=1;
}
else
{
modify(lid,l,r,c0,c1,opt);
modify(rid,l,r,c0,c1,opt);
update(k);
}
}//从小到大
else
{
if(tr[k].r<=l+c1-1)
{
tr[k].cnt1=tr[k].r-tr[k].l+1;
tr[k].cnt0=0;
tr[k].fl=1;
}
else if(tr[k].l>=l+c1)
{
tr[k].cnt1=0;
tr[k].cnt0=tr[k].r-tr[k].l+1;
tr[k].fl=0;
}
else
{
modify(lid,l,r,c0,c1,opt);
modify(rid,l,r,c0,c1,opt);
update(k);
}
}//从大到小
return;
}
int mid=(tr[k].l+tr[k].r)>>1;
if(tr[k].fl!=-1)
pushdown(k);
if(l<=mid)
modify(lid,l,r,c0,c1,opt);
if(r>mid)
modify(rid,l,r,c0,c1,opt);
update(k);
}//区间修改
int query(int k,int l,int r,int opt)
{
if(tr[k].l>=l&&tr[k].r<=r)
return (opt==0)?tr[k].cnt0:tr[k].cnt1;
int mid=(tr[k].l+tr[k].r)>>1;
int ret=0;
if(tr[k].fl!=-1)
pushdown(k);
if(l<=mid)
ret+=query(lid,l,r,opt);
if(r>mid)
ret+=query(rid,l,r,opt);
return ret;
}//查询0/1个数
int query_p(int k,int pos)
{
if(tr[k].l==tr[k].r)
return tr[k].cnt1;
int mid=(tr[k].l+tr[k].r)>>1;
if(tr[k].fl!=-1)
pushdown(k);
if(pos<=mid)
return query_p(lid,pos);
else return query_p(rid,pos);
}//单点查询
int check(int r)
{
build(1,1,n,r);//建树
// printf("\n");
for(int i=1;i<=m;++i)
{
int cnt0,cnt1;
cnt0=query(1,lq[i],rq[i],0);//查询0的数量
cnt1=query(1,lq[i],rq[i],1);//查询1的数量
modify(1,lq[i],rq[i],cnt0,cnt1,op[i]);
}
if(query_p(1,q))return 1;
else return 0;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
for(int i=1;i<=m;++i)
scanf("%d%d%d",&op[i],&lq[i],&rq[i]);
scanf("%d",&q);
int l=1,r=n;
while(l<r)
{
int mid=(l+r)>>1;
//printf("mid=%d ",mid);
if(check(mid))l=mid+1;
else r=mid;
}
printf("%d",l-1);
return 0;
}
这个是正确代码
#include<cstdio>
#define maxn 100005
#define lid (k<<1)
#define rid (k<<1|1)
using namespace std;
struct node
{
int l,r;
int cnt0,cnt1;//记录0和1的数量
int fl;//lazy标记
}tr[maxn*4];
int n,m,q;
int a[maxn],lq[maxn],rq[maxn],op[maxn];
void update(int k)
{
tr[k].cnt0=tr[lid].cnt0+tr[rid].cnt0;
tr[k].cnt1=tr[lid].cnt1+tr[rid].cnt1;
}
void pushdown(int k)
{
int l=tr[k].l,r=tr[k].r;
int mid=(l+r)>>1;
if(tr[k].fl==0)
{
tr[lid].cnt0=mid-l+1;
tr[lid].cnt1=0;
tr[rid].cnt0=r-mid;
tr[rid].cnt1=0;
tr[lid].fl=tr[rid].fl=0;
}
else
{
tr[lid].cnt0=0;
tr[lid].cnt1=mid-l+1;
tr[rid].cnt0=0;
tr[rid].cnt1=r-mid;
tr[lid].fl=tr[rid].fl=1;
}
tr[k].fl=-1;
}
void build(int k,int l,int r,int val)
{
tr[k].l=l;
tr[k].r=r;
tr[k].fl=-1;
tr[k].cnt0=tr[k].cnt1=0;
if(l==r)
{
if(a[l]>=val)tr[k].cnt1=1;
else tr[k].cnt0=1;
return;
}
int mid=(l+r)>>1;
build(lid,l,mid,val);
build(rid,mid+1,r,val);
update(k);
}//将大于mid的值赋为1,小于mid的值赋为0
void modify(int k,int l,int r,int opt)
{
if(tr[k].l>=l&&tr[k].r<=r)
{
if(opt)
{
tr[k].cnt1=tr[k].r-tr[k].l+1;
tr[k].cnt0=0;
tr[k].fl=1;
}
else
{
tr[k].cnt0=tr[k].r-tr[k].l+1;
tr[k].cnt1=0;
tr[k].fl=0;
}
return;
}
int mid=(tr[k].l+tr[k].r)>>1;
if(tr[k].fl!=-1)
pushdown(k);
if(l<=mid)
modify(lid,l,r,opt);
if(r>mid)
modify(rid,l,r,opt);
update(k);
}//区间修改
int query(int k,int l,int r,int opt)
{
if(tr[k].l>=l&&tr[k].r<=r)
return (opt==0)?tr[k].cnt0:tr[k].cnt1;
int mid=(tr[k].l+tr[k].r)>>1;
int ret=0;
if(tr[k].fl!=-1)
pushdown(k);
if(l<=mid)
ret+=query(lid,l,r,opt);
if(r>mid)
ret+=query(rid,l,r,opt);
return ret;
}//查询0/1个数
int query_p(int k,int pos)
{
if(tr[k].l==tr[k].r)
return tr[k].cnt1;
int mid=(tr[k].l+tr[k].r)>>1;
if(tr[k].fl!=-1)
pushdown(k);
if(pos<=mid)
return query_p(lid,pos);
else return query_p(rid,pos);
}//单点查询
int check(int r)
{
build(1,1,n,r);//建树
for(int i=1;i<=m;++i)
{
int cnt0,cnt1;
cnt0=query(1,lq[i],rq[i],0);//查询0的数量
cnt1=query(1,lq[i],rq[i],1);//查询1的数量
if(op[i])
{
modify(1,lq[i],lq[i]+cnt1-1,1);
modify(1,rq[i]-cnt0+1,rq[i],0);
}
else
{
modify(1,lq[i],lq[i]+cnt0-1,0);
modify(1,rq[i]-cnt1+1,rq[i],1);
}
}
return query_p(1,q);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
for(int i=1;i<=m;++i)
scanf("%d%d%d",&op[i],&lq[i],&rq[i]);
scanf("%d",&q);
int l=1,r=n;
while(l<r)
{
int mid=(l+r)>>1;
if(check(mid))l=mid+1;
else r=mid;
}
printf("%d",l-1);
return 0;
}
它们只有check函数和modify函数不一样,但我觉得这两个程序是相同的,各位大佬能帮忙看一下问题出在哪里吗?