社区讨论
为什么这两篇代码常数差很多
P2824[HEOI2016/TJOI2016] 排序参与者 3已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @mjcxnqh7
- 此快照首次捕获于
- 2025/12/19 21:56 2 个月前
- 此快照最后确认于
- 2025/12/21 15:30 2 个月前
第一篇代码
CPP#include <iostream>
using namespace std;
int n,m,q;
int a[100005];
struct node
{
int l,r,sum,lazy;
};
node t[400005];
int b[100005];
void build(int id,int l,int r)
{
if(l==r)
t[id].sum=b[l];
else
{
int mid=l+r>>1;
build(id*2,l,mid);
build(id*2+1,mid+1,r);
t[id].sum=t[id*2].sum+t[id*2+1].sum;
}
t[id].l=l;
t[id].r=r;
t[id].lazy=-1;
}
void pushup(int id)
{
if(t[id].lazy!=-1)
{
t[id].sum=t[id].lazy*(t[id].r-t[id].l+1);
if(t[id].l!=t[id].r)
t[id*2].lazy=t[id*2+1].lazy=t[id].lazy;
t[id].lazy=-1;
}
}
void cover(int id,int l,int r,int k)
{
if(r<l)
return ;
if(t[id].l==l&&t[id].r==r)
{
t[id].lazy=k;
pushup(id);
return ;
}
pushup(id);
int mid=t[id].l+t[id].r>>1;
if(r<=mid)
cover(id*2,l,r,k);
else if(l>mid)
cover(id*2+1,l,r,k);
else
cover(id*2,l,mid,k),cover(id*2+1,mid+1,r,k);
pushup(id*2);
pushup(id*2+1);
t[id].sum=t[id*2].sum+t[id*2+1].sum;
}
int query(int id,int l,int r)
{
if(r<l)
return 0;
pushup(id);
if(t[id].l==l&&t[id].r==r)
return t[id].sum;
int mid=(t[id].l+t[id].r)/2;
if(r<=mid)
return query(id*2,l,r);
else if(mid<l)
return query(id*2+1,l,r);
return query(id*2,l,mid)+query(id*2+1,mid+1,r);
}
struct node_
{
int op,l,r;
};
node_ op[100005];
bool check(int limit)
{
for(int i=1;i<=n;i++)
if(a[i]>=limit)
b[i]=1;
else
b[i]=0;
build(1,1,n);
for(int i=1;i<=m;i++)
{
int p=query(1,op[i].l,op[i].r);
int q=op[i].r-op[i].l+1-p;
if(op[i].op==0)
{
cover(1,op[i].l,op[i].l+q-1,0);
cover(1,op[i].r-p+1,op[i].r,1);
}
else
{
cover(1,op[i].l,op[i].l+p-1,1);
cover(1,op[i].r-q+1,op[i].r,0);
}
}
return query(1,q,q)==1;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=m;i++)
cin>>op[i].op>>op[i].l>>op[i].r;
cin>>q;
int l=0x3f3f3f3f,r=-0x3f3f3f3f;
for(int i=1;i<=n;i++)
{
if(a[i]<l)
l=a[i];
if(a[i]>r)
r=a[i];
}
while(l!=r)
{
int mid=(l+r+1)/2;
if(check(mid))
l=mid;
else
r=mid-1;
}
cout<<l;
return 0;
}
第二篇代码
CPP#include <iostream>
using namespace std;
int n,m,q;
int a[100005],b[100005];
int op[100005],l[100005],r[100005];
int t[400005],lazy[400005];
void build(int id,int l,int r)
{
lazy[id]=-0x3f3f3f3f;
if(l==r)
t[id]=b[l];
else
{
int mid=(l+r)>>1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
t[id]=t[id<<1]+t[id<<1|1];
}
}
void tag(int id,int l,int r,int lz)
{
t[id]=(r-l+1)*lz;
lazy[id]=lz;
}
void pushdown(int id,int l,int r)
{
if(lazy[id]!=-0x3f3f3f3f&&l!=r)
{
int mid=(l+r)>>1;
tag(id<<1,l,mid,lazy[id]);
tag(id<<1|1,mid+1,r,lazy[id]);
}
lazy[id]=-0x3f3f3f3f;
}
int query(int id,int l,int r,int L,int R)
{
if(L<=l&&r<=R)
return t[id];
pushdown(id,l,r);
int mid=(l+r)>>1;
int ans=0;
if(L<=mid)
ans+=query(id<<1,l,mid,L,R);
if(R>mid)
ans+=query(id<<1|1,mid+1,r,L,R);
return ans;
}
void change(int id,int l,int r,int L,int R,int d)
{
if(L>r||l>R) return ;
if(L<=l&&r<=R)
{
tag(id,l,r,d);
return ;
}
pushdown(id,l,r);
int mid=(l+r)>>1;
if(L<=mid)
change(id<<1,l,mid,L,R,d);
if(R>mid)
change(id<<1|1,mid+1,r,L,R,d);
t[id]=t[id<<1]+t[id<<1|1];
}
bool check(int limit)
{
for(int i=1;i<=n;i++)
b[i]=a[i]>=limit;
build(1,1,n);
for(int i=1;i<=m;i++)
{
int k=r[i]-l[i]+1-query(1,1,n,l[i],r[i]);
if(op[i]==0)
change(1,1,n,l[i],l[i]+k-1,0),change(1,1,n,l[i]+k,r[i],1);
else
change(1,1,n,l[i],l[i]+(r[i]-l[i]+1-k)-1,1),change(1,1,n,l[i]+(r[i]-l[i]+1-k),r[i],0);
}
if(query(1,1,n,q,q)==1)
return true;
return false;
}
int main()
{
cin>>n>>m;
int mn=-0x3f3f3f3f,mx=0x3f3f3f3f;
for(int i=1;i<=n;i++)
cin>>a[i],mn=min(mn,a[i]),mx=max(mx,a[i]);
for(int i=1;i<=m;i++)
cin>>op[i]>>l[i]>>r[i];
cin>>q;
int l=mn,r=mx;
while(l!=r)
{
int mid=(l+r+1)>>1;
if(check(mid))
l=mid;
else
r=mid-1;
}
cout<<r;
return 0;
}
第一篇代码是暑假写的,第二篇代码是今天写的。
第一篇代码只跑了 6 秒多,第二篇代码跑了 10 秒,但是我完全不知道是什么东西导致常数大了这么多。
回复
共 2 条回复,欢迎继续交流。
正在加载回复...