Educational Codeforces Round 90(Rated for Div.2)G.Pawns(線分樹)


G.Pawns
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
out put
スタンダードアウト
You are given a checssboard consisting of nn ローソンand nn columns.Rows are numberred from bottom to top from 11 ト nn.Columns are numberged from left to right from 11 ト nn.The cel at the intersection of the x-th column and the yy-th row is denoted as (x,y)(x,y).Frthere,the kk-th column is a special column.
Initially,the board is empty.The re are mm changes to the board.During the i-th change one pawn is added or removed from the board.The current board is good if we can move all pawns to the special column by the followwings rules:
  • Pawn in the cell (x,y)(x,y) can be moved to the cell (x,y+1)(x,y+1) (x−1,y+1)(x−1,y+1) or (x+1,y+1)(x+1,y+1)
  • You can make as many such moves as you like;
  • Pawns can not be moved outside the checssboard;
  • Each cell can not contain more than one pawn.
  • The current board may not always be good.To fix it,you can add new rows to the board.New rows are ard ard.net added at the top,i.̵e.they will have numbers n+1,n+2,n+3,...n+1,n+2,n+3,....
    After each of mm changes、print one integer-the minimum number of rows which you have to add to make the board good.
    Input
    The first line contains three integers nn kk and mm (1≦n、m≦2⋅105;1≦k≦n 1≦n、m≦2⋅105;1≦k≦n)—the size of the board、the index of the special column and the number of changes pective.
    The n mm lins follow.The i-th LINE contains two integers xx and yy (1≦x,y≦n 1≦x,y≦n)—the index of the column and the index of the row rectively.If there isのpawn in the cell (x,y)(x,y)、then you add a pawn to this cell、otherwise—you remove the pawn from this cell.
    Output
    After each change print one integer-the minimum number of rows which you have to add to make the board good.
    Example
    input
    Copy
    5 3 5
    4 4
    3 5
    2 4
    3 4
    3 5
    
    out put
    Copy
    0
    1
    2
    2
    1
    n*n(==2 e 5)のボードをあげます.その中でk列目は特殊で、m(==2 e 5)の操作を行います.
    毎回操作して一つの座標(x,y)を与えます.第x列のy行を表します.この点に駒がない場合は一つを入れます.そうでないとポイントの駒を持って行きます.
    毎回操作した後に、各駒(x,y)が(x-1,y+1)、(x,y+1)、(x+1,y+1)にしか移動できないなら、移動回数は制限されないと思いますが、少なくとも何行を追加すれば、すべての駒がk列に移動できますか?操作のたびに一つの数を出力して答えを表します.
    解析:考えにくいですね.駒は1ステップずつ移動するので、行数は必ず+1になります.だから、この駒はk列目に移動する時の最小の行数posを計算できます.この駒はk列目の任意の行数>=posの位置に移動できます.
    ただの検索なら、まずすべてのpos上の駒の数を記録して、最後にk列の最初の行から下に掃きます.すべての駒が異なる行数を獲得するまで.しかし、m回の調査なので、私達は守るべきものがあります.
    最も巧妙なところ:k列目のある行のposに対して、前の行が十分にpos-1行前の駒を並べるならば、pos位置の駒の数はposという位置を決めて、下に何行を追加する必要がありますか?最大のposの駒の数は最後の答えを確定します.前の行がpos-1行の前の駒を置くのに足りないなら、実際にはposの位置の駒の個数(解答に対する影響)はpos-1の位置に置くのに相当します.
    したがって、下付きi=[1,n+n]を初期化した値はi-1(注意posは最大2*n-1)となり、各駒に対応してk列目の位置がposとなり、下付き[1,pos]に対応する値をすべて+1とし、各下付きの値はこの行から下のすべての後の駒の最終行数を表します.線分樹でメンテナンスして最大値を取ればいいです.注意0時の特殊処理.配列のサイズに注意します.
    コード:
    #include
    #define ll long long
    #define inf 0x3f3f3f3f
    #define mst(head,x,n) memset(head+1,x,n*sizeof(head[0]))
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define dep(i,a,b) for(int i=(a);i>=(b);i--)
    #define lson rt<<1
    #define rson rt<<1|1
    using namespace std;
    const int maxn=4e5+5;
    //const double pi=acos(-1.0);
    //const double eps=1e-9;
    //const ll mo=1e9+7;
    int n,m,k;
    int a[maxn<<2],c[maxn<<2],num[maxn<<2];
    int ans,tmp,cnt;
    int flag;
    template 
    inline void read(T &X){
        X=0;int w=0; char ch=0;
        while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
        while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        if(w) X=-X;
    }
    void pu(int rt){
        c[rt]=max(c[lson],c[rson]);
    }
    void pd(int rt){
        if(a[rt]){
            c[lson]+=a[rt];
            c[rson]+=a[rt];
            a[lson]+=a[rt];
            a[rson]+=a[rt];
            a[rt]=0;
        }
    }
    void build(int rt,int l,int r){
        if(l==r){
            c[rt]=l-1;
            a[rt]=0;
            return ;
        }
        int mid=(l+r)>>1;
        build(lson,l,mid);
        build(rson,mid+1,r);
        pu(rt);
    }
    void update(int rt,int l,int r,int L,int R,int v){
        if(L<=l&&r<=R){
            a[rt]+=v;
            c[rt]+=v;
            return ;
        }
        pd(rt);
        int mid=(l+r)>>1;
        if(L<=mid) update(lson,l,mid,L,R,v);
        if(R>mid) update(rson,mid+1,r,L,R,v);
        pu(rt);
    }
    int query(int rt,int l,int r,int L,int R){
        if(L<=l&&r<=R){
            return c[rt];
        }
        pd(rt);
        int mid=(l+r)>>1;
        int ans=0;
        if(L<=mid) ans=max(ans,query(lson,l,mid,L,R));
        if(R>mid) ans=max(ans,query(rson,mid+1,r,L,R));
        //pu(rt);
        return ans;
    }
    int main(){
    
    #ifdef ONLINE_JUDGE
    #else
        freopen("D:/Temp/in.txt", "r", stdin);
    #endif
    
        int T,cas=1;
        //read(T);
        //while(T--)
        {
            read(n);read(k);read(m);
            set >st;
            setlst;
            build(1,1,n+n);
            rep(i,1,m){
                int x,y;
                read(x);read(y);
                int pos=y+abs(x-k);
                pairp=make_pair(x,y);
                if(st.count(p)){
                    num[pos]--;
                    if(num[pos]==0) lst.erase(pos);
                    st.erase(p);
                    update(1,1,n+n,1,pos,-1);
                }
                else {
                    st.insert(p);
                    num[pos]++;
                    if(num[pos]==1) lst.insert(pos);
                    update(1,1,n+n,1,pos,1);
                }
                //cout<