[POI2014]Cards

题目大意:
  有$n(n\le2\times10^5)$张卡片排成一排,每张卡片正反面有两个数$a_i$和$b_i$。$m(m\le10^6)$次操作,每次交换第$c_i$和第$d_i$张卡片,问若可以任意翻转卡片,是否存在一种方案使得卡片上的数字构成一个不下降序列。

思路:
  用线段树维护区间,左端点取最大/小值时,右端点取最大值还是最小值。

 1 #include<cstdio>
 2 #include<cctype>
 3 #include<algorithm>
 4 inline int getint() {
 5     register char ch;
 6     while(!isdigit(ch=getchar()));
 7     register int x=ch^'0';
 8     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
 9     return x;
10 }
11 const int N=200001;
12 int a[N][2];
13 class SegmentTree {
14     #define _left <<1
15     #define _right <<1|1
16     private:
17         int val[N<<2][2];
18         void push_up(const int &p,const int &b,const int &e) {
19             const int mid=(b+e)>>1;
20             val[p][0]=val[p][1]=-1;
21             if(val[p _left][0]==-1) return;
22             if(a[mid+1][1]>=a[mid][val[p _left][0]]) val[p][0]=val[p _right][1];
23             if(a[mid+1][0]>=a[mid][val[p _left][0]]) val[p][0]=val[p _right][0];
24             if(val[p _left][1]==-1) return;
25             if(a[mid+1][1]>=a[mid][val[p _left][1]]) val[p][1]=val[p _right][1];
26             if(a[mid+1][0]>=a[mid][val[p _left][1]]) val[p][1]=val[p _right][0];
27         }
28     public:
29         void build(const int &p,const int &b,const int &e) {
30             if(b==e) {
31                 val[p][0]=0;
32                 val[p][1]=1;
33                 return;
34             }
35             const int mid=(b+e)>>1;
36             build(p _left,b,mid);
37             build(p _right,mid+1,e);
38             push_up(p,b,e);
39         }
40         void modify(const int &p,const int &b,const int &e,const int &x) {
41             if(b==e) return;
42             const int mid=(b+e)>>1;
43             if(x<=mid) modify(p _left,b,mid,x);
44             if(x>mid) modify(p _right,mid+1,e,x);
45             push_up(p,b,e);
46         }
47         bool query() const {
48             return val[1][0]!=-1;
49         }
50     #undef _left
51     #undef _right
52 };
53 SegmentTree t;
54 int main() {
55     const int n=getint();
56     for(register int i=1;i<=n;i++) {
57         a[i][0]=getint(),a[i][1]=getint();
58         if(a[i][0]>a[i][1]) std::swap(a[i][0],a[i][1]);
59     }
60     t.build(1,1,n);
61     for(register int m=getint();m;m--) {
62         const int x=getint(),y=getint();
63         std::swap(a[x][0],a[y][0]);
64         std::swap(a[x][1],a[y][1]);
65         t.modify(1,1,n,x);
66         t.modify(1,1,n,y);
67         puts(t.query()?"TAK":"NIE");
68     }
69     return 0;
70 }

 

posted @ 2018-03-26 09:23  skylee03  阅读(172)  评论(0编辑  收藏  举报