• 洛谷P3569 [POI2014]KAR-Cards(线段树)


    传送门

    蠢了……

    我们用线段树,记$w0$为该区间最左端取小值时,最右端最小能取大还是小还是无解,$w1$表示最左端取大值时,最右端最小能取大还是小还是无解

    然后只要把交换看做修改就好了

    这么说可能很难懂,看看代码应该就明白了

     1 //minamoto
     2 #include<iostream>
     3 #include<cstdio>
     4 using namespace std;
     5 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     6 char buf[1<<21],*p1=buf,*p2=buf;
     7 int read(){
     8     #define num ch-'0'
     9     char ch;bool flag=0;int res;
    10     while(!isdigit(ch=getc()))
    11     (ch=='-')&&(flag=true);
    12     for(res=num;isdigit(ch=getc());res=res*10+num);
    13     (flag)&&(res=-res);
    14     #undef num
    15     return res;
    16 }
    17 const int N=3e5+5;
    18 int a[N][2],w0[N<<2],w1[N<<1];
    19 #define ls (p<<1)
    20 #define rs (p<<1|1)
    21 void upd(int p,int l,int r){
    22     int mid=(l+r)>>1,t;
    23     if((t=w0[ls])==-1) w0[p]=-1;
    24     else{
    25         t=a[mid][t];
    26         if(t<=a[mid+1][0]) w0[p]=w0[rs];
    27         else if(t<=a[mid+1][1]) w0[p]=w1[rs];
    28         else w0[p]=-1;
    29     }
    30     if((t=w1[ls])==-1) w1[p]=-1;
    31     else{
    32         t=a[mid][t];
    33         if(t<=a[mid+1][0]) w1[p]=w0[rs];
    34         else if(t<=a[mid+1][1]) w1[p]=w1[rs];
    35         else w1[p]=-1;
    36     }
    37 }
    38 void build(int p,int l,int r){
    39     if(l==r) return (void)(w0[p]=0,w1[p]=1);
    40     int mid=(l+r)>>1;
    41     build(ls,l,mid),build(rs,mid+1,r);
    42     upd(p,l,r);
    43 }
    44 void update(int p,int l,int r,int x){
    45     if(l==r) return;
    46     int mid=(l+r)>>1;
    47     x<=mid?update(ls,l,mid,x):update(rs,mid+1,r,x);
    48     upd(p,l,r);
    49 }
    50 int main(){
    51 //    freopen("testdata.in","r",stdin);
    52     int n=read();
    53     for(int i=1;i<=n;++i){
    54         a[i][0]=read(),a[i][1]=read();
    55         if(a[i][0]>a[i][1]) swap(a[i][0],a[i][1]);
    56     }
    57     build(1,1,n);
    58     int m=read();
    59     while(m--){
    60         int x=read(),y=read();swap(a[x][0],a[y][0]),swap(a[x][1],a[y][1]);
    61         update(1,1,n,x),update(1,1,n,y);
    62         puts(w0[1]==-1?"NIE":"TAK");
    63     }
    64     return 0;
    65 }
  • 相关阅读:
    相机篇
    ValueAnimator动画跳过中间过程的问题
    android 双向文字问题
    android让xml布局的底部跟随软键盘
    给fragment设置进入和退出动画
    android布局控件的LayoutParams
    注意点
    关于与条件判断中的顺序
    栈的反转
    从尾到头打印链表
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9812997.html
Copyright © 2020-2023  润新知