zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    CC
    codeforces 984 E. Elevator
    codeforces 984 D. XOR-pyramid
    codeforces 984 C. Finite or not?
    codeforces 984 B. Minesweeper
    codeforces 984 A. Game
    Loj #6000. 「网络流 24 题」搭配飞行员
    2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest 训练报告
    省赛训练 分块9题
    AC自动机 hdu 2222 Keywords Search
  • 原文地址:https://www.cnblogs.com/yousiki/p/6527563.html
Copyright © 2011-2022 走看看