爱线段树的好孩子[POI2014]KAR-Cards

23 篇文章 0 订阅
16 篇文章 0 订阅

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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值