BZOJ3526: [Poi2014]Card

来源:互联网 发布:php数组做分页 编辑:程序博客网 时间:2024/06/04 19:18

一开始没读懂题意以为操作之间互不影响….然后写了个长长的st表WA了..

用a[i][0/1]代表第i个卡片的正反面,线段树上每个点维护一个v[0/1][0/1]表示这个区间左右卡片的状态,在这个状态下这个区间是否能合法

code:

#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long longusing namespace std;inline void read(int &x){    char c; while(!((c=getchar())>='0'&&c<='9'));    x=c-'0';    while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0';}const int maxn = 210000;const int maxd = 20;int n,m;int a[maxn][2];struct segment{bool v[2][2];}seg[maxn<<2];void build(const int x,const int l,const int r){    memset(seg[x].v,false,sizeof seg[x].v);    if(l==r) { seg[x].v[0][0]=seg[x].v[1][1]=true; return; }    int mid=l+r>>1,lc=x<<1,rc=lc|1;    build(lc,l,mid),build(rc,mid+1,r);    for(int k0=0;k0<2;k0++) for(int k1=0;k1<2;k1++) if(seg[lc].v[k0][k1])        for(int k2=0;k2<2;k2++) for(int k3=0;k3<2;k3++) if(seg[rc].v[k2][k3])            if(a[mid][k1]<=a[mid+1][k2]) seg[x].v[k0][k3]=true;}int loc;void upd(const int x,const int l,const int r){    memset(seg[x].v,false,sizeof seg[x].v);    if(l==r) { seg[x].v[0][0]=seg[x].v[1][1]=true; return; }    int mid=l+r>>1,lc=x<<1,rc=lc|1;    if(loc<=mid) upd(lc,l,mid);    else upd(rc,mid+1,r);    for(int k0=0;k0<2;k0++) for(int k1=0;k1<2;k1++) if(seg[lc].v[k0][k1])        for(int k2=0;k2<2;k2++) for(int k3=0;k3<2;k3++) if(seg[rc].v[k2][k3])            if(a[mid][k1]<=a[mid+1][k2]) seg[x].v[k0][k3]=true;}int main(){    read(n);    for(int i=1;i<=n;i++)     {        read(a[i][0]),read(a[i][1]);        if(a[i][0]>a[i][1]) swap(a[i][0],a[i][1]);    }    build(1,1,n);    read(m);    while(m--)    {        int x,y; read(x); read(y);        swap(a[x][0],a[y][0]); swap(a[x][1],a[y][1]);        loc=x; upd(1,1,n);        loc=y; upd(1,1,n);        bool re=false;        for(int k0=0;k0<2;k0++) for(int k1=0;k1<2;k1++) if(seg[1].v[k0][k1]) re=true;        puts(re?"TAK":"NIE");    }    return 0;}