講道理省選場上出現這種bc#76 原題的行爲真的不厚道。。。。一是因爲規模這麼大一比賽很少有人不知道,二是人家題解就擺在網上的。。。丫樣例都不改
難不成把多組數據改成一組數據也叫改編?(23333
主要思路就是二分猜答案之後,將原序列改成01序列(小於等於mid的變成0,否則變成1)用線段樹維護排序操作。
/**************************************************************
Problem: 4552
User: RicardoWang
Language: C++
Result: Accepted
Time:12976 ms
Memory:11428 kb
****************************************************************/
#include<cstdlib>
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#define maxn 200005
using namespace std;
int A[maxn],v[maxn];
struct data
{
int op,x,y;
}B[maxn];
int n,M,q;
void Init()
{
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",&B[i].op,&B[i].x,&B[i].y);
scanf("%d",&q);
return ;
}
int np,rt;
int cnt[2*maxn],chi[2*maxn][2],down[2*maxn];
void build(int &now,int L,int R)
{
now=++np;cnt[now]=down[now]=0;
chi[now][0]=chi[now][1]=0;
if(L==R)
{
cnt[now]=v[L]; return ;
}
int mid =(L+R)>>1;
build(chi[now][0],L,mid);
build(chi[now][1],mid+1,R);
cnt[now]=cnt[chi[now][0]]+cnt[chi[now][1]];
return ;
}
void pushdown(int now,int L,int R)
{
int mid=(L+R)>>1;
if(down[now])
{
down[chi[now][0]]=down[chi[now][1]]=down[now];
cnt[chi[now][0]]=(mid-L+1)*(down[now]-1);
cnt[chi[now][1]]=(R-mid)*(down[now]-1);
}
down[now]=0;
return ;
}
void update(int now,int L,int R,int x,int y,int v)
{
if(x<=L && R<=y)
{
down[now]=v+1; cnt[now]=v*(R-L+1);
return ;
}
pushdown(now,L,R);
int mid=(L+R)>>1;
if(x<=mid)update(chi[now][0],L,mid,x,y,v);
if(y>mid)update(chi[now][1],mid+1,R,x,y,v);
cnt[now]=cnt[chi[now][0]]+cnt[chi[now][1]];
return;
}
int query(int now,int L,int R,int x,int y)
{
if(x<=L && R<=y)
{
return cnt[now];
}
pushdown(now,L,R);
int mid=(L+R)>>1;
int t1=0,t2=0;
if(x<=mid)t1=query(chi[now][0],L,mid,x,y);
if(y>mid)t2=query(chi[now][1],mid+1,R,x,y);
cnt[now]=cnt[chi[now][0]]+cnt[chi[now][1]];
return t1+t2;
}
bool check(int x)
{
for(int i=1;i<=n;i++)
{
v[i]=A[i]<=x? 0:1;
}
np=0;int ct;
build(rt,1,n);
for(int i=1;i<=M;i++)
{
ct=query(rt,1,n,B[i].x,B[i].y);
if(B[i].op==0)
{
ct=B[i].y-B[i].x+1-ct;
if(ct>0)update(rt,1,n,B[i].x,B[i].x+ct-1,0);
if(ct<=B[i].y-B[i].x)update(rt,1,n,B[i].x+ct,B[i].y,1);
}
else
{
if(ct>0)update(rt,1,n,B[i].x,B[i].x+ct-1,1);
if(ct<=B[i].y-B[i].x)update(rt,1,n,B[i].x+ct,B[i].y,0);
}
// for(int j=1;j<=n;j++)printf("%d ",query(rt,1,n,j,j));
// putchar('\n');
}
return query(rt,1,n,q,q)==0;
}
void work()
{
int l=1,r=n,mid,ans;
while(l<=r)
{
mid=(l+r)>>1;
if(check(mid))
{
r=mid-1; ans=mid;
}
else
{
l=mid+1;
}
}
printf("%d\n",ans);
return ;
}
int main()
{
// freopen("in.txt","r",stdin);
int T=1;
while(T--)
{
Init();
work();
}
return 0;
}