【BZOJ】4552 排序

講道理省選場上出現這種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;
}


發佈了61 篇原創文章 · 獲贊 1 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章