[IOI2018] seats 排座位

[IOI2018] seats 排座位 

IOI2018题解

压缩状态思想很不错的

每次把原来的贡献减掉,新来的再加上

最多涉及10个点

注意:

1.去重

2.下标从0开始

3.线段树初始的最小值个数都是r-l+1

代码:

 

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define mid ((l+r)>>1)
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){
    char ch;x=0;bool fl=false;
    while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
    for(x=numb;isdigit(ch=getchar());x=x*10+numb);
    (fl==true)&&(x=-x);
}
namespace Miracle{
const int N=1000000+5;
const int inf=0x3f3f3f3f;
int id[N],vis[N],sta[N],top;
int pos[N][2];
int n,m,q;
int num(int x,int y){
    return (x-1)*m+y;
}
struct tr{
    int mi,cnt;
    int mx;
    int ad;
}t[4*N];
void pushup(int x){
    t[x].mi=min(t[x<<1].mi,t[x<<1|1].mi);
    t[x].mx=max(t[x<<1].mx,t[x<<1|1].mx);
    t[x].cnt=t[x<<1].cnt*(t[x<<1].mi==t[x].mi)+t[x<<1|1].cnt*(t[x<<1|1].mi==t[x].mi);
}
void pushdown(int x){
    if(!t[x].ad) return;
    t[x<<1].ad+=t[x].ad;
    t[x<<1].mi+=t[x].ad;
    t[x<<1].mx+=t[x].ad;
    t[x<<1|1].ad+=t[x].ad;
    t[x<<1|1].mi+=t[x].ad;
    t[x<<1|1].mx+=t[x].ad;
    
    t[x].ad=0;
}
void build(int x,int l,int r){
    if(l==r){
        t[x].cnt=1;return;
    }
    build(x<<1,l,mid);
    build(x<<1|1,mid+1,r);
    pushup(x);
}
void add(int x,int l,int r,int L,int R,int c){
    if(L<=l&&r<=R){
        t[x].ad+=c;
        t[x].mi+=c;
        t[x].mx+=c;
        if(t[x].mi==t[x].mx) t[x].cnt=r-l+1;
        return;
    }    
    pushdown(x);
    if(L<=mid) add(x<<1,l,mid,L,R,c);
    if(mid<R) add(x<<1|1,mid+1,r,L,R,c);
    pushup(x);
}
int mv[4][2]={{+1,0},{-1,0},{0,+1},{0,-1}};
void wrk1(int x,int y,int c){
    //cout<<" x y "<<x<<" "<<y<<" c "<<c<<endl;
    int mi=inf,cmi=inf;
    for(reg i=0;i<4;++i){
        int dx=x+mv[i][0],dy=y+mv[i][1];
        if(dx>=1&&dx<=n&&dy>=1&&dy<=m){
            if(id[num(dx,dy)]<mi){
                cmi=mi;mi=id[num(dx,dy)];
            }else cmi=min(cmi,id[num(dx,dy)]);
        }
    }
    
    if(cmi<=id[num(x,y)]-1) {
        //cout<<" x y "<<x<<" "<<y<<" : "<<mi<<" "<<cmi<<endl;
        add(1,1,n*m,cmi,id[num(x,y)]-1,c);
    }
}
void wrk2(int x,int y,int c){
    int mi=n*m+1;
    int dx=x-1,dy=y;
    if(dx>=1&&dx<=n&&dy>=1&&dy<=m){
        mi=min(mi,id[num(dx,dy)]);
    }
    dx=x,dy=y-1;
    if(dx>=1&&dx<=n&&dy>=1&&dy<=m){
        mi=min(mi,id[num(dx,dy)]);
    }
    //cout<<" x y "<<x<<" "<<y<<" mimimi "<<mi<<endl;
    if(id[num(x,y)]<=mi-1) add(1,1,n*m,id[num(x,y)],mi-1,c);
}
void sol(int x,int y,int c){
    //cout<<" sol "<<x<<" "<<y<<" c "<<c<<endl;
    if(!vis[num(x,y)]) {
        sta[++top]=num(x,y);
        vis[num(x,y)]=1;
        wrk1(x,y,c);wrk2(x,y,c);
    }
    for(reg i=0;i<4;++i){
        int dx=x+mv[i][0],dy=y+mv[i][1];
        if(dx>=1&&dx<=n&&dy>=1&&dy<=m&&!vis[num(dx,dy)]){
            vis[num(dx,dy)]=1;
            sta[++top]=num(dx,dy);
            wrk1(dx,dy,c);wrk2(dx,dy,c);
        }
    }
}
int main(){
    rd(n);rd(m);rd(q);
    build(1,1,n*m);
    int x,y;
    for(reg i=1;i<=n*m;++i){
        rd(x);rd(y);
        ++x;++y;
        pos[i][0]=x;pos[i][1]=y;
        id[num(x,y)]=i;
    }
    for(reg i=1;i<=n;++i){
        for(reg j=1;j<=m;++j){
            wrk1(i,j,1);
            wrk2(i,j,1);
        }
    }
    //cout<<t[1].mi<<" "<<t[1].mx<<" "<<t[1].cnt<<endl;
    int A,B;
    while(q--){
        rd(A);rd(B);        
        ++A;++B;
        top=0;
        
        x=pos[A][0],y=pos[A][1];
        sol(x,y,-1);
        x=pos[B][0],y=pos[B][1];
        sol(x,y,-1);
        
        while(top) vis[sta[top--]]=0;
        swap(id[num(pos[A][0],pos[A][1])],id[num(pos[B][0],pos[B][1])]);
        swap(pos[A][0],pos[B][0]);
        swap(pos[A][1],pos[B][1]);
        
        x=pos[A][0],y=pos[A][1];
        sol(x,y,1);
        x=pos[B][0],y=pos[B][1];
        sol(x,y,1);
        
        while(top) vis[sta[top--]]=0;
        
        int ans=0;
        if(t[1].mi==1) ans=t[1].cnt;
        printf("%d\n",ans);
    }
    return 0;
}

}
signed main(){
    Miracle::main();
    return 0;
}

/*
   Author: *Miracle*
   Date: 2019/2/10 17:53:31
*/

 

posted @ 2019-02-10 20:20  *Miracle*  阅读(606)  评论(0编辑  收藏  举报