• [POI2014]Cards


    题目大意:
      有$n(nle2 imes10^5)$张卡片排成一排,每张卡片正反面有两个数$a_i$和$b_i$。$m(mle10^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 }
  • 相关阅读:
    KMP字符串查找
    基数排序
    二分查找来查找旋转数组
    通过前序(后序)+中序创建树
    二维数组找最大值
    用字符串的空格替换其他字符
    桶排序
    字符串的排列
    和为S的两个数字
    整数中1出现的次数(从1到n整数中1出现的次数)
  • 原文地址:https://www.cnblogs.com/skylee03/p/8648700.html
Copyright © 2020-2023  润新知