BZOJ 3526: [Poi2014]Card

3526: [Poi2014]Card

Time Limit: 25 Sec  Memory Limit: 64 MB
Submit: 267  Solved: 191
[Submit][Status][Discuss]

Description

有n张卡片在桌上一字排开,每张卡片上有两个数,第i张卡片上,正面的数为a[i],反面的数为b[i]。现在,有m个熊孩子来破坏你的卡片了!
第i个熊孩子会交换c[i]和d[i]两个位置上的卡片。
每个熊孩子捣乱后,你都需要判断,通过任意翻转卡片(把正面变为反面或把反面变成正面,但不能改变卡片的位置),能否让卡片正面上的数从左到右单调不降。

 

Input

第一行一个n。
接下来n行,每行两个数a[i],b[i]。
接下来一行一个m。
接下来m行,每行两个数c[i],d[i]。

 

Output

m行,每行对应一个答案。如果能成功,输出TAK,否则输出NIE。

 

Sample Input

4
2 5
3 4
6 3
2 7
2
3 4
1 3

Sample Output

NIE
TAK

HINT

 



【样例解释】

交换3和4后,卡片序列为(2,5) (3,4) (2,7) (6,3),不能成功。

交换1和3后,卡片序列为(2,7) (3,4) (2,5) (6,3),翻转第3张卡片,卡片的正面为2,3,5,6,可以成功。


【数据范围】

n≤200000,m≤1000000,0≤a[i],b[i]≤10000000,1≤c[i],d[i]≤n.

 

Source

[Submit][Status][Discuss]

 

好有趣的一道题,老早就写过,现在又重新写一遍,强行缩代码,2333.

 

就是用线段树,维护每个区间,如果选取区间左端较小值,右端能以什么结尾;如果选取区间左端较大值,右端能以什么结尾。

 

 1 #include<cstdio>
 2 #define mxn 200005
 3 #define siz 800005
 4 #define mxm 1000005
 5 #define swap(a,b) a^=b^=a^=b
 6 int n,m,a[mxn],b[mxn],c,d,A[siz],B[siz];
 7 void update(int t,int l,int r,int d,int ls,int rs){
 8     A[t]=B[t]=0;
 9     if((A[ls]==1&&a[d]<=b[d+1])||(A[ls]==2&&b[d]<=b[d+1]))A[t]=B[rs];
10     if((A[ls]==1&&a[d]<=a[d+1])||(A[ls]==2&&b[d]<=a[d+1]))A[t]=A[rs];
11     if((B[ls]==1&&a[d]<=b[d+1])||(B[ls]==2&&b[d]<=b[d+1]))B[t]=B[rs];
12     if((B[ls]==1&&a[d]<=a[d+1])||(B[ls]==2&&b[d]<=a[d+1]))B[t]=A[rs];
13 }
14 void build(int t,int l,int r){
15     if(l==r){A[t]=1;B[t]=2;return;}
16     int d=(l+r)>>1,ls=t<<1,rs=t<<1|1;
17     build(ls,l,d),build(rs,d+1,r);
18     update(t,l,r,d,ls,rs);
19 }
20 void rebuild(int t,int l,int r,int p){
21     if(l==r){A[t]=1;B[t]=2;return;}
22     int d=(l+r)>>1,ls=t<<1,rs=t<<1|1;
23     if(p<=d)rebuild(ls,l,d,p);else rebuild(rs,d+1,r,p);
24     update(t,l,r,d,ls,rs);
25 }
26 main(){
27     scanf("%d",&n);
28     for(int i=1;i<=n;++i)scanf("%d%d",a+i,b+i);
29     for(int i=1;i<=n;++i)if(a[i]>b[i])swap(a[i],b[i]);
30     build(1,1,n);
31     scanf("%d",&m);
32     for(int i=1;i<=m;++i)scanf("%d%d",&c,&d),puts((swap(a[c],a[d]),swap(b[c],b[d]),rebuild(1,1,n,c),rebuild(1,1,n,d),A[1])?"TAK":"NIE");
33 }

 

原来的代码看起来好冗长的样子……

  1 #include <cmath>
  2 #include <cstdio>
  3 #include <string>
  4 #include <cstring>
  5 #include <cstdlib> 
  6 #include <iostream>
  7 #include <algorithm>
  8  
  9 using namespace std;
 10  
 11 const int N = 200005;
 12 const int M = 1000005;
 13  
 14 int n, m;
 15  
 16 struct card
 17 {
 18     int a, b;
 19      
 20     card(void) {};
 21     card(int _a, int _b)
 22     {
 23         a = min(_a, _b);
 24         b = max(_a, _b);
 25     }
 26 }c[N];
 27  
 28 struct node
 29 {
 30     int lt, rt;
 31     int valA, valB;
 32 }tree[N << 2];
 33  
 34 void buildTree(int p, int l, int r)
 35 {
 36     node &t = tree[p];
 37      
 38     t.lt = l, t.rt = r;
 39      
 40     if (t.lt == t.rt)
 41     {
 42         t.valA = 1;
 43         t.valB = 2;
 44          
 45         return;
 46     }
 47      
 48     int mid = (t.lt + t.rt) >> 1;
 49      
 50     buildTree(p << 1, t.lt, mid);
 51     buildTree(p << 1 | 1, mid + 1, t.rt);
 52      
 53     t.valA = t.valB = 0;
 54      
 55     switch (tree[p << 1].valA)
 56     {
 57         case 1:
 58             if (c[mid].a <= c[mid + 1].b)
 59                 t.valA = tree[p << 1 | 1].valB;
 60             if (c[mid].a <= c[mid + 1].a)
 61                 t.valA = tree[p << 1 | 1].valA;
 62             break;
 63         case 2:
 64             if (c[mid].b <= c[mid + 1].b)
 65                 t.valA = tree[p << 1 | 1].valB;
 66             if (c[mid].b <= c[mid + 1].a)
 67                 t.valA = tree[p << 1 | 1].valA;
 68             break;
 69     }
 70      
 71     switch (tree[p << 1].valB)
 72     {
 73         case 1: 
 74             if (c[mid].a <= c[mid + 1].b)
 75                 t.valB = tree[p << 1 | 1].valB;
 76             if (c[mid].a <= c[mid + 1].a)
 77                 t.valB = tree[p << 1 | 1].valA;
 78             break;
 79         case 2: 
 80             if (c[mid].b <= c[mid + 1].b)
 81                 t.valB = tree[p << 1 | 1].valB;
 82             if (c[mid].b <= c[mid + 1].a)
 83                 t.valB = tree[p << 1 | 1].valA;
 84             break;
 85     }
 86 }
 87  
 88 void change(int p, int pos)
 89 {
 90     node &t = tree[p];
 91      
 92     if (t.lt == t.rt)
 93     {
 94         t.valA = 1;
 95         t.valB = 2;
 96          
 97         return;
 98     }
 99      
100     int mid = (t.lt + t.rt) >> 1;
101      
102     if (pos <= mid)
103         change(p << 1, pos);
104     else
105         change(p << 1 | 1, pos);
106          
107     t.valA = t.valB = 0;
108  
109     switch (tree[p << 1].valA)
110     {
111         case 1:
112             if (c[mid].a <= c[mid + 1].b)
113                 t.valA = tree[p << 1 | 1].valB;
114             if (c[mid].a <= c[mid + 1].a)
115                 t.valA = tree[p << 1 | 1].valA;
116             break;
117         case 2:
118             if (c[mid].b <= c[mid + 1].b)
119                 t.valA = tree[p << 1 | 1].valB;
120             if (c[mid].b <= c[mid + 1].a)
121                 t.valA = tree[p << 1 | 1].valA;
122             break;
123     }
124      
125     switch (tree[p << 1].valB)
126     {
127         case 1:
128             if (c[mid].a <= c[mid + 1].b)
129                 t.valB = tree[p << 1 | 1].valB;
130             if (c[mid].a <= c[mid + 1].a)
131                 t.valB = tree[p << 1 | 1].valA;
132             break;
133         case 2:
134             if (c[mid].b <= c[mid + 1].b)
135                 t.valB = tree[p << 1 | 1].valB;
136             if (c[mid].b <= c[mid + 1].a)
137                 t.valB = tree[p << 1 | 1].valA;
138             break;
139     }
140 }
141  
142 signed main(void)
143 {
144     scanf("%d", &n);
145      
146     for (int i = 1, a, b; i <= n; ++i)
147         scanf("%d%d", &a, &b), c[i] = card(a, b);
148      
149     buildTree(1, 1, n);
150      
151     scanf("%d", &m);
152      
153     for (int i = 1, a, b; i <= m; ++i)
154     {
155         scanf("%d%d", &a, &b);
156          
157         swap(c[a], c[b]);
158          
159         change(1, a);
160         change(1, b);
161          
162         if (tree[1].valA)
163             puts("TAK");
164         else
165             puts("NIE");
166     }
167 }

 

@Author: YouSiki

 

posted @ 2017-03-09 20:12  YouSiki  阅读(208)  评论(0编辑  收藏  举报