[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);}
原创粉丝点击