【BZOJ4534】基础排序算法练习题

来源:互联网 发布:网站美工制作 编辑:程序博客网 时间:2024/06/02 06:51

#以后看见这种题目名字2B的我直接绕道走

#%%%策爷

#讲道理这种论文题我都没脸写题解

主要工作分为两部分,一部分是在(n^2+m)log(n)内预处理完所有操作,用一个序列代表所有可以被成功排序的序列,另一部分是qnlog(n)处理每个询问

#大家快去%%%吧!

/**************************************************************    Problem: 4534    User: RicardoWang    Language: C++    Result: Accepted    Time:9656 ms    Memory:9336 kb****************************************************************/ #include<cstdlib>#include<cstdio>#include<iostream>#include<cstring>#include<cmath>#include<algorithm>#include<queue>#include<vector>#include<set>using namespace std;#define MAXN 3005 #define MAXM 1010005void _read(int &x){    char ch=getchar(); bool flag=false;  x=0;    while(ch<'0' || ch>'9'){if(ch=='-')flag=true; ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} if(flag)x=-x; return ;}int N,M,Q,A[MAXN],C[MAXN],_C[MAXN],_A[MAXN];set<int>S;set<int> :: iterator it;int nowid;void solve(int x,int y){    if(S.empty())return ;    it=S.lower_bound(x);    while(*it<y && *it>=x)    {        nowid=*it;swap(A[nowid],A[nowid+1]);         S.erase(it);         if(nowid>1 && A[nowid-1]>A[nowid])        {            if(A[nowid-1]>A[nowid])            {                if(S.count(nowid-1)==0)S.insert(nowid-1);            }            else            {                if(S.count(nowid-1)==1)S.erase(nowid-1);            }                   }        if(nowid<N-1 )        {            if(A[nowid+1]>A[nowid+2])            {                if(S.count(nowid+1)==0)S.insert(nowid+1);            }            else            {                if(S.count(nowid+1)==1) S.erase(nowid+1);            }        }                  if(!S.empty())it=S.lower_bound(x);              else break;    }    return ;}struct QQ{    int x,y;}q[MAXM];struct data{    int x,id;}B[MAXN];bool cmp2(int x,int y){    return x>y;}void Init(){    _read(N); _read(M); _read(Q); int x,y;    for(int i=1;i<=N;i++) { A[i]=N+1-i;} //倒序处理     for(int i=1;i<N;i++)S.insert(i);    for(int i=1;i<=M;i++) {_read(x); _read(y); q[M+1-i]=(QQ){x,y};}    for(int i=1;i<=M;i++) {x=q[i].x; y=q[i].y; solve(N+1-y,N+1-x);}    for(int i=1;i<=N;i++)_A[i]=A[N+1-i];   //    for(int i=1;i<=N;i++)A[i]=i;  //    for(int i=1;i<=M;i++)sort(A+q[i].x,A+q[i].y+1,cmp2);    for(int i=1;i<=N;i++)A[_A[i]]=i;    return ;    }bool cmp(data x,data y){    if(x.x==y.x)return x.id<y.id;    else return x.x<y.x;}int np,rt,chi[2*MAXN][2],minv[2*MAXN],down[2*MAXN];void build(int &now,int L,int R){    now=++np; minv[now]=down[now]=0;    if(L==R)return ;    int m=(L+R)>>1; build(chi[now][0],L,m); build(chi[now][1],m+1,R); return ;}void push_down(int now){    if(down[now])    {        down[chi[now][0]]+=down[now];down[chi[now][1]]+=down[now];        minv[chi[now][0]]+=down[now];minv[chi[now][1]]+=down[now];        down[now]=0;    }    return ;}void update(int now,int L,int R,int x,int y,int v){    if(x<=L && R<=y)    {        minv[now]+=v; down[now]+=v;        return ;    }    push_down(now);    int m=(L+R)>>1; if(x<=m)update(chi[now][0],L,m,x,y,v); if(y>m)update(chi[now][1],m+1,R,x,y,v);    minv[now]=min(minv[chi[now][0]],minv[chi[now][1]]);    return ;}void work(){    bool flag;    np=0;    build(rt,1,N);    for(int i=1;i<=Q;i++)    {        flag=true;        for(int j=1;j<=np;j++)minv[j]=down[j]=0;        for(int j=1;j<=N;j++) _read(B[j].x);        for(int j=1;j<=N;j++) B[j].id=j;        sort(B+1,B+1+N,cmp);        for(int j=1;j<=N;j++)C[j]=B[j].id;        for(int k=N;k>=1;k--)        {            update(rt,1,N,C[k],N,-1);             update(rt,1,N,A[k],N,1);            if(minv[rt]<0){ flag=false; break;}        }        if(flag){putchar('A'); putchar('C'); }        else {putchar('W'); putchar('A'); }        if(i!=Q)putchar('\n');    }    return ;}int main(){   // freopen("in.txt","r",stdin);  //  freopen("out.txt","w",stdout);    Init();    work();    return 0;}



0 0
原创粉丝点击