[bzoj4552][Tjoi2016&Heoi2016]排序-二分+线段树
来源:互联网 发布:python 股票回测系统 编辑:程序博客网 时间:2024/05/20 16:11
线段树而已;
参考:http://blog.csdn.net/werkeytom_ftd/article/details/51366237
和http://www.cnblogs.com/gengchen/p/6613566.html
题目大意有一个n的排列,进行m次操作,每次操作是将一个区间升序或降序排序。请你输出m次操作后第p个位置的值。二分答案我们二分答案x,然后就是判断a[p]>=x?
#include <cstdio>#define init int l = t[k].l, r = t[k].r, mid = (l + r) >> 1const int maxn = 1e5 + 1e2;int n, m, a[maxn], lambda, q;struct seg { int l, r, val, cov;} t[maxn << 4];struct op { int a, b, c;} o[maxn];void update(int k) { t[k].val = t[k << 1].val + t[k << 1 | 1].val; }void build(int k, int l, int r) { t[k].l = l, t[k].r = r, t[k].cov = -1; if (l == r) { t[k].val = a[l] > lambda; return; } int mid = (l + r) >> 1; build(k << 1, l, mid); build(k << 1 | 1, mid + 1, r); update(k);}void pushdown(int k) { if (t[k].cov != -1) { t[k << 1].cov = t[k].cov; t[k << 1 | 1].cov = t[k].cov; t[k << 1].val = (t[k << 1].r - t[k << 1].l + 1) * (t[k].cov); t[k << 1 | 1].val = (t[k << 1 | 1].r - t[k << 1 | 1].l + 1) * (t[k].cov); t[k].cov = -1; } if (t[k].l < t[k].r) update(k);}int query(int k, int x, int y) { init; pushdown(k); if (x <= l && r <= y) return t[k].val; int ans = 0; if (x <= mid) ans += query(k << 1, x, y); if (y > mid) ans += query(k << 1 | 1, x, y); return ans;}void modify(int k, int x, int y, int val) { init; pushdown(k); if (x <= l && r <= y) { t[k].val = (r - l + 1) * val; t[k].cov = val; return; } if (x <= mid) modify(k << 1, x, y, val); if (y > mid) modify(k << 1 | 1, x, y, val); update(k);}bool check(int x) { lambda = x; build(1, 1, n); for (int i = 1; i <= m; i++) { int opt = o[i].a, x = o[i].b, y = o[i].c; int tmp = query(1, x, y); if (opt == 0) { modify(1, x, y - tmp, 0); modify(1, y - tmp + 1, y, 1); } else { modify(1, x, x + tmp - 1, 1); modify(1, x + tmp, y, 0); } } return !query(1, q, q);}int main() {#ifndef ONLINE_JUDGE freopen("input", "r", stdin);#endif scanf("%d %d", &n, &m); for (int i = 1; i <= n; ++i) scanf("%d", &a[i]); int l = 1, r = n; for (int i = 1; i <= m; i++) { scanf("%d %d %d", &o[i].a, &o[i].b, &o[i].c); } scanf("%d", &q); while (l < r) { int mid = (l + r) >> 1; if (check(mid)) r = mid; else l = mid + 1; } printf("%d", r);}
我的代码又错了..
#include<bits/stdc++.h>using namespace std;#define N 100050#define md ((ll+rr)>>1)#define ls (i<<1)#define rs (ls|1)#define lson ls,ll,md#define rson rs,md+1,rrint n,m;int ans;int a[N];int ask[N][3];int lazy[N*5];int sum[N*5];int p;void ch(){ for(int i=1;i<=n;++i)printf("%d",sum[i]);puts("");}void down(int i,int ll,int rr){ if(lazy[i]==-1)return; sum[ls]=(md-ll+1)*lazy[i]; sum[rs]=(rr-md)*lazy[i]; lazy[ls]=lazy[rs]=lazy[i]; lazy[i]=-1;}int query(int i,int ll,int rr,int l,int r){ if(l==ll&&rr==r){ return sum[i]; } down(i,ll,rr); if(r<=md)return query(ls,ll,md,l,r); else if(l>md)return query(rs,md+1,rr,l,r); else{ return query(lson,l,md)+query(rson,md+1,r); }}void update(int i,int ll,int rr,int l,int r,int val){ if(l==ll&&rr==r){ lazy[i]=val; sum[i]=(rr-ll+1)*val; return ; } down(i,ll,rr); //cout<<md<<endl; //printf("%d %d\n %d %d\n",ll,rr,l,r); if(r<=md)update(lson,l,r,val); else if(l>md)update(rson,l,r,val); else update(lson,l,md,val),update(rson,md+1,r,val); sum[i]=sum[ls]+sum[rs];}bool ok(int mid){ memset(lazy,-1,sizeof(lazy)); //ch(); for(int i=1;i<=n;++i) if(a[i]<mid)update(1,1,n,i,i,0); else update(1,1,n,i,i,1); for(int i=1;i<=m;++i){ int t=query(1,1,n,ask[i][1],ask[i][2]); if(ask[i][0]){ update(1,1,n,ask[i][1],ask[i][1]+t-1,1); update(1,1,n,ask[i][1]+t-1,ask[i][2],0); } else{ update(1,1,n,ask[i][1],ask[i][2]-t+1,0); update(1,1,n,ask[i][2]-t+1,ask[i][2],1); } } return !query(1,1,n,p,p);}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",&ask[i][0],&ask[i][1],&ask[i][2]); } int l=0,r=n; scanf("%d",&p); while(l<=r){ int mid=(l+r)>>1; if(ok(mid))ans=mid,r=mid-1; else l=mid+1; } printf("%d\n",ans);}
阅读全文
0 0
- [BZOJ4552][Tjoi2016&Heoi2016][线段树][二分]排序
- [bzoj4552][Tjoi2016&Heoi2016]排序 二分+线段树
- [bzoj4552][Tjoi2016&Heoi2016]排序-二分+线段树
- 【bzoj4552】【Tjoi2016】【Heoi2016】【排序】【二分答案】【线段树】
- [BZOJ4552][Tjoi2016&Heoi2016]排序 二分答案+线段树
- 【二分+线段树】BZOJ4552(Tjoi2016&Heoi2016)[排序]题解
- bzoj4552 [ TJOI2016 && HEOI2016 ] -- 二分+线段树
- 【bzoj4552】【Tjoi2016&Heoi2016】【排序】【线段树】
- BZOJ4552: [Tjoi2016&Heoi2016]排序 线段树
- [BZOJ4552][TJOI2016&HEOI2016]排序-线段树合并
- BZOJ4552 [Tjoi2016&Heoi2016]排序
- bzoj4552【TJOI2016&HEOI2016】排序
- 【bzoj4552】 [Tjoi2016&Heoi2016]排序
- [bzoj4552][Tjoi2016&Heoi2016]排序
- bzoj4552: [Tjoi2016&Heoi2016]排序
- [ 线段树套treap ] [ TJOI2016&&HEOI2016 ] BZOJ4552
- TJOI2016&HEOI2016 排序 线段树+二分答案
- bzoj 4552: [Tjoi2016&Heoi2016]排序 二分答案+线段树
- JAVA中几种字符串翻转的方法
- HDU-2955 Robberies (01背包 入门题)
- win10下的文件和打印机共享
- hive 动态分区
- Hibernate Tools安装教程
- [bzoj4552][Tjoi2016&Heoi2016]排序-二分+线段树
- MATLAB向量,矩阵创建和转换
- IDirect3DDevice9::Clear函数
- 算法学习(1):最短路径—Dijkstra算法和Floyd算法
- CI中site_url()和base_url()的区别
- jquery.chosen.js实现模糊搜索
- django-rest搜索排序字段使用
- Java中Map接口HashMap与HashTable的区别及HashMap深入理解
- 尴尬