线段树而已;
参考:http://blog.youkuaiyun.com/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) >> 1
const 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,rr
int 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);
}