3130 排序
来源:互联网 发布:免费英语口语软件 编辑:程序博客网 时间:2024/06/01 19:18
Task
给出1-n的全排列,m次操作分为两种:
① (0,l,r)将区间[l,r]升序排列
② (1,l,r)将区间[l,r]降序排列。
n,m<=1e5
Solution
6秒的时限,真是个暴力的好时机
用sort函数sort(A+l,A+r+1,cmp)可以对区间[l,r]升序或者降序排列,这样就有80分了。
但是本人粗鄙,写成了sort(A+l+1,A+r+1),居然还有60分
想到平时的sort都是(A,A+n)或(A+1,A+n+1),分别是左端点,右端点+1的位置。
“二分是一个方向”
二分的好处:把求知问题转化为判定问题。
类似的题目:区间第k值,中位数。
二分x,判定解是否大于等于x.按照x,记大于等于x的数为1,小于x的数为0。对于m次操作后,如果id位上的数为1,判定为可行。
问题转化为,一个01序列,m次操作后,第id位上的数是否为1。
①因为一个区间只有01,无论是升序降序,都有1个0和1的分界点。因为区间的长度是一定的,对区间求和,可以找到1的个数。
②按照分界线前部分为c,后部分为c^1.(c为0或1).
区间求和,区间更新,可以用延迟更新的线段树完成。
const int M=1e5+3;int A[M];int n,m,pos;struct node1{ int cnt[2],l,r,f; inline void clear(){ memset(cnt,0,sizeof(cnt)); }}res;struct node2{ int a,l,r;}Q[M];struct Segment_Tree{ node1 t[M<<2]; inline void up(int p){ rep(i,0,1) t[p].cnt[i]=t[lsn(p)].cnt[i]+t[rsn(p)].cnt[i]; } inline void down(int p){ if(t[p].f==-1)return; int c=t[p].f,l=lsn(p),r=rsn(p); t[l].f=t[r].f=c; t[l].cnt[c]=t[l].r-t[l].l+1; t[r].cnt[c]=t[r].r-t[r].l+1; t[l].cnt[c^1]=t[r].cnt[c^1]=0; t[p].f=-1; } inline void build(int l,int r,int x,int p){ t[p].l=l,t[p].r=r;t[p].f=-1; if(l==r){ bool a=(A[l]>=x); t[p].cnt[a]=1;t[p].cnt[a^1]=0; return; } int mid=l+r>>1; build(l,mid,x,lsn(p)); build(mid+1,r,x,rsn(p)); up(p); } inline void query(int L,int R,int l,int r,int p){ if(l==L&&r==R){ rep(i,0,1)res.cnt[i]+=t[p].cnt[i]; return; } down(p); int mid=L+R>>1; if(r<=mid)query(L,mid,l,r,lsn(p)); else if(l>mid)query(mid+1,R,l,r,rsn(p)); else{ query(L,mid,l,mid,lsn(p)); query(mid+1,R,mid+1,r,rsn(p)); } } inline void update(int L,int R,int l,int r,int c,int p){//区间刷成c颜色 if(l==L&&r==R){ t[p].cnt[c]=r-l+1; t[p].cnt[c^1]=0; t[p].f=c; return; } down(p); int mid=L+R>>1; if(r<=mid)update(L,mid,l,r,c,lsn(p)); else if(l>mid)update(mid+1,R,l,r,c,rsn(p)); else{ update(L,mid,l,mid,c,lsn(p)); update(mid+1,R,mid+1,r,c,rsn(p)); } up(p); }}T;struct P100{ inline void input(){ rd(n);rd(m); rep(i,1,n)rd(A[i]); rep(i,1,m){ rd(Q[i].a);rd(Q[i].l);rd(Q[i].r); } rd(pos); } inline bool check(int x){//解是否>=x int a,l,r; T.build(1,n,x,1); rep(i,1,m){ res.clear(); a=Q[i].a,l=Q[i].l,r=Q[i].r; T.query(1,n,l,r,1); if(min(res.cnt[0],res.cnt[1])==0)continue;//这个区间都是0或1 T.update(1,n,l,l+res.cnt[a]-1,a,1);//区间刷成颜色a T.update(1,n,l+res.cnt[a],r,a^1,1);//区间刷成颜色a^1 } res.clear(); T.query(1,n,pos,pos,1); return res.cnt[1]==1; } inline void solve(){ input(); int l=1,r=n,mid,ans; while(l<=r){ mid=l+r>>1; if(check(mid)){l=mid+1;ans=mid;} else r=mid-1; } sc(ans); }}P100;int main(){ P100.solve(); return 0;}
0 0
- 3130 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- 排序
- Atmeg128a
- Agri-Net
- 盒子与球问题的探讨
- BIOS/UEFI基础——UEFI网络框架之UNDI
- 解压deb包时遇到 “dpkg status database is locked by another process”问题
- 3130 排序
- C 堆栈的链式表示
- JS高级---ajax
- 模式匹配、字符串匹配(蛮力法)
- 上课笔记set_new_handler的实现
- python 中的算数运算符
- POJ 3087Shuffle'm Up(模拟)
- 分享两款强大的文本编辑器
- BIOS/UEFI基础——UEFI网络框架之SNP