• 【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;
    }
  • 相关阅读:
    Action返回类型
    低成本FPGA中实现动态相位调整
    SERDES高速系统(二)
    SERDES高速系统(一)
    Avalon总线概述
    FPGA热设计
    功耗的挑战
    特性阻抗介绍
    低阻抗电源分配系统
    非理想回路信号衰减
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4986026.html
Copyright © 2020-2023  润新知