1. 程式人生 > >和Leo一起做愛線段樹的好孩子[POI2014]KAR-Cards

和Leo一起做愛線段樹的好孩子[POI2014]KAR-Cards

There are nn cards arranged on a table in a certain order.

Two integers are written on each card, one per side: the obverse and the reverse.

Initially all cards lie with the averse facing up.

Byteasar, The Great Illusionist, intends to perform (multiple times!) his signature Binary Search Card Manipulation. However, to present it, he needs the sequence of numbers as seen on the cards to be non-decreasing.

Thus, Byteasar may have to turn over some cards so that the numbers on their reverse sides become visible.

Furthermore, the illusion requires a participant from the audience.

Alas, some of the volunteers are deployed by Byteasar's competitors who want him to fail.

Each such supposititious volunteer, upon entering the scene, would swap two cards on the table in a lightning move of a hand. After each such swap, Byteasar can again turn over any cards he desires but nevertheless, he may not be able to perform his great illusion.

If that were to happen, he would be forced to turn to traditional illusions, such as pulling a rabbit out of a hat.

Write a program that determines, after each card swap, if Byteasar can perform his great illusion.

有一些卡牌,正反各有一個數,你可以任意翻轉,每次操作會將兩張卡牌的位置調換,你需要在每次操作後回答以現在的卡牌順序能否通過反轉形成一個單調不降的序列

維護:當前選這個數右端點最小值為多少

#include<bits/stdc++.h>
using namespace std;
#define lc (p<<1)
#define rc (p<<1|1)
const int INF=1e9+7;
const int N=2e5+100;
inline void read(int &x){
    x=0;
    int f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';
        ch=getchar();
    }
    x*=f;
}
int a[N<<2][2];
struct Sgement_Tree{	
    int T[N<<2][2];
    void PushUp(int p,int l,int r){
        T[p][0]=T[p][1]=INF;
        int mid=(l+r)>>1;
        if(T[lc][0]<=a[mid+1][0])T[p][0]=min(T[p][0],T[rc][0]);
        if(T[lc][1]<=a[mid+1][0])T[p][1]=min(T[p][1],T[rc][0]);
        if(T[lc][0]<=a[mid+1][1])T[p][0]=min(T[p][0],T[rc][1]);
        if(T[lc][1]<=a[mid+1][1])T[p][1]=min(T[p][1],T[rc][1]);
    }
    void build(int p,int l,int r){
        if(l==r){
            T[p][0]=a[l][0];
            T[p][1]=a[l][1];
            return;
        }
        int mid=(l+r)>>1;
        build(lc,l,mid);
        build(rc,mid+1,r);
        PushUp(p,l,r);	
    }
    void Update(int p,int l,int r,int pos){
        if(l==r){
            T[p][0]=a[l][0];
            T[p][1]=a[l][1];
            return;
        }
        int mid=(l+r)>>1;
        if(pos<=mid)Update(lc,l,mid,pos);
        else Update(rc,mid+1,r,pos);
        PushUp(p,l,r);
    }
}Solution;
int n,m;
int main(){
//	freopen("test.in","r",stdin);
    read(n);
    for(int i=1;i<=n;++i)read(a[i][0]),read(a[i][1]);
    Solution.build(1,1,n);
    read(m);
    for(int i=1;i<=m;++i){
        int x,y;
        read(x);
        read(y);
        swap(a[x][0],a[y][0]);
        swap(a[x][1],a[y][1]);
        Solution.Update(1,1,n,x);
        Solution.Update(1,1,n,y);
        if(Solution.T[1][0]<INF||Solution.T[1][1]<INF)cout<<"TAK"<<'\n';
        else cout<<"NIE"<<'\n';
    }
    return 0;
}