zoukankan      html  css  js  c++  java
  • 【BZOJ】3526: [Poi2014]Card

    题意

    (n(n le 200000))张卡片,正反有两个数(a[i], b[i])(m(m le 1000000))次操作,每次交换(c[i]、d[i])位置上的卡片。每一次操作后输出是否存在一种方案使得正面朝上的数从左到右单调不降。

    分析

    直接考虑线段树维护。

    题解

    线段树每个结点记录4个信息(a[i][j]),表示左边的(i)在这个结点区间能否和右边的(j)面满足条件,update的时候更新一下即可。

    #include <bits/stdc++.h>
    using namespace std;
    inline int getint() {
    	int x=0;
    	char c=getchar();
    	for(; c<'0'||c>'9'; c=getchar());
    	for(; c>='0'&&c<='9'; x=x*10+c-'0', c=getchar());
    	return x;
    }
    const int N=200005, Lim=N*3;
    int a[N][2], n;
    struct node {
    	node *c[2];
    	bool g[2][2];
    	void up(int m) {
    		static int *l, *r;
    		static bool f[2][2];
    		l=a[m], r=a[m+1];
    		f[0][0]=l[0]<=r[0];
    		f[0][1]=l[0]<=r[1];
    		f[1][0]=l[1]<=r[0];
    		f[1][1]=l[1]<=r[1];
    		g[0][0]=(c[0]->g[0][0]&&((c[1]->g[0][0]&&f[0][0])||(c[1]->g[1][0]&&f[0][1])))||
    				(c[0]->g[0][1]&&((c[1]->g[0][0]&&f[1][0])||(c[1]->g[1][0]&&f[1][1])));
    		g[0][1]=(c[0]->g[0][0]&&((c[1]->g[0][1]&&f[0][0])||(c[1]->g[1][1]&&f[0][1])))||
    				(c[0]->g[0][1]&&((c[1]->g[0][1]&&f[1][0])||(c[1]->g[1][1]&&f[1][1])));
    		g[1][0]=(c[0]->g[1][0]&&((c[1]->g[0][0]&&f[0][0])||(c[1]->g[1][0]&&f[0][1])))||
    				(c[0]->g[1][1]&&((c[1]->g[0][0]&&f[1][0])||(c[1]->g[1][0]&&f[1][1])));
    		g[1][1]=(c[0]->g[1][0]&&((c[1]->g[0][1]&&f[0][0])||(c[1]->g[1][1]&&f[0][1])))||
    				(c[0]->g[1][1]&&((c[1]->g[0][1]&&f[1][0])||(c[1]->g[1][1]&&f[1][1])));
    	}
    	void init() {
    		g[0][0]=g[1][1]=1;
    	}
    }Po[Lim], *iT=Po, *root;
    node *build(int l, int r) {
    	node *x=iT++;
    	if(l==r) {
    		x->init();
    		return x;
    	}
    	int mid=(l+r)>>1;
    	x->c[0]=build(l, mid);
    	x->c[1]=build(mid+1, r);
    	x->up(mid);
    	return x;
    }
    void update(int p, int l=1, int r=n, node *x=root) {
    	if(l==r) {
    		return;
    	}
    	int mid=(l+r)>>1, f=p>mid;
    	f?(l=mid+1):(r=mid);
    	update(p, l, r, x->c[f]);
    	x->up(mid);
    }
    int main() {
    	n=getint();
    	for(int i=1; i<=n; ++i) {
    		a[i][0]=getint();
    		a[i][1]=getint();
    	}
    	root=build(1, n);
    	int m=getint();
    	while(m--) {
    		int x=getint(), y=getint();
    		swap(a[x][0], a[y][0]);
    		swap(a[x][1], a[y][1]);
    		update(x);
    		update(y);
    		puts((root->g[0][0]||root->g[0][1]||root->g[1][0]||root->g[1][1])?"TAK":"NIE");
    	}
    	return 0;
    }
  • 相关阅读:
    AJAX初步学习
    MyBatis 中@param 的用法
    MyBatis 分页
    MyBatis 中一对一和一对多的映射关系
    MyBatis的增删改查。
    MyBatis配置文件
    java 中 “==” 和 equals 的区别
    点云格式-pcd
    VS2015+VisualSVN+TortoiseSVN安装及使用
    GIS中的引擎:地图引擎
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4986026.html
Copyright © 2011-2022 走看看