[HEOI2016/TJOI2016]排序
https://www.luogu.com.cn/problem/P2824
题解:仔细思考可以发现这道题与https://arc101.contest.atcoder.jp/tasks/arc101_b?lang=en 是等价的。二分之后原问题就转化为了序列,可以直接用线段树维护。
#include<iostream>
using namespace std;
struct node
{
int l,r,data,lazy;
};
struct reads
{
int op,l,r;
};
node tree[1000001];
reads q[1000001];
int a[1000001],p[1000001],n,m,Q;
void build(int k,int l,int r)
{
tree[k].l=l;
tree[k].r=r;
tree[k].lazy=-1;
int mid=(l+r)/2;
if (l==r)
{
tree[k].data=p[l];
return;
}
build(k*2,l,mid);
build(k*2+1,mid+1,r);
tree[k].data=tree[k*2].data+tree[k*2+1].data;
return;
}
void spread(int k)
{
if (tree[k].lazy==0)
{
tree[k].lazy=-1;
tree[k*2].lazy=tree[k*2+1].lazy=tree[k*2].data=tree[k*2+1].data=0;
return;
}
if (tree[k].lazy==1)
{
tree[k].lazy=-1;
tree[k*2].data=tree[k*2].r-tree[k*2].l+1;
tree[k*2+1].data=tree[k*2+1].r-tree[k*2+1].l+1;
tree[k*2].lazy=tree[k*2+1].lazy=1;
return;
}
return;
}
void add(int k,int l,int r,int d)
{
if (l>r)
return;
if (tree[k].l==l&&tree[k].r==r)
{
tree[k].data=d*(tree[k].r-tree[k].l+1);
tree[k].lazy=d;
return;
}
spread(k);
int mid=(tree[k].l+tree[k].r)/2;
if (l<=mid&&r<=mid)
{
add(k*2,l,r,d);
tree[k].data=tree[k*2].data+tree[k*2+1].data;
return;
}
if (l>=mid+1&&r>=mid+1)
{
add(k*2+1,l,r,d);
tree[k].data=tree[k*2].data+tree[k*2+1].data;
return;
}
add(k*2,l,mid,d);
add(k*2+1,mid+1,r,d);
tree[k].data=tree[k*2].data+tree[k*2+1].data;
return;
}
int sum(int k,int l,int r)
{
if (tree[k].l==l&&tree[k].r==r)
return tree[k].data;
spread(k);
int mid=(tree[k].l+tree[k].r)/2;
if (l<=mid&&r<=mid)
return sum(k*2,l,r);
if (l>=mid+1&&r>=mid+1)
return sum(k*2+1,l,r);
return sum(k*2,l,mid)+sum(k*2+1,mid+1,r);
}
bool msort(int S)
{
int res;
for (int i=1;i<=n;++i)
p[i]=(a[i]>=S);
build(1,1,n);
for (int i=1;i<=m;++i)
{
res=sum(1,q[i].l,q[i].r);
if (q[i].op==0)
{
add(1,q[i].l,q[i].r-res,0);
add(1,q[i].r-res+1,q[i].r,1);
}
else
{
add(1,q[i].l,q[i].l+res-1,1);
add(1,q[i].l+res,q[i].r,0);
}
}
return sum(1,Q,Q);
}
int main()
{
cin>>n>>m;
for (int i=1;i<=n;++i)
cin>>a[i];
for (int i=1;i<=m;++i)
cin>>q[i].op>>q[i].l>>q[i].r;
cin>>Q;
int first=1,last=n,mid,ans=1;
while (first<=last)
{
mid=(first+last)/2;
if (msort(mid))
{
ans=max(ans,mid);
first=mid+1;
}
else
last=mid-1;
}
cout<<ans<<endl;
return 0;
}
作者:zhouhuanyi
出处:https://www.cnblogs.com/zhouhuanyi/p/16983586.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通