BZOJ3526 [Poi2014]Card 【线段树】

题目链接

BZOJ3526

题解

思来想去,发现很显然可以用线段树维护
每个区间保存所有合法方案的左右端点【当左端点一定是,右端点当然存最小的那个就行了】

这么整的数,\(\frac{1}{1000}\)的概率啊23333

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
#define ls (u << 1)
#define rs (u << 1 | 1)
using namespace std;
const int maxn = 200005,maxm = 100005,INF = 1000000000;
inline int read(){
	int out = 0,flag = 1; char c = getchar();
	while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
	while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
	return out * flag;
}
int ln[maxn << 2][2],rn[maxn << 2][2],cnt[maxn << 2];
int a[maxn],b[maxn],n,m;
void upd(int u){
	if (!cnt[ls] || !cnt[rs]) cnt[u] = 0;
	else {
		cnt[u] = 0;
		for (int i = 0; i < cnt[ls]; i++){
			int r = INF;
			for (int j = 0; j < cnt[rs]; j++){
				if (rn[ls][i] <= ln[rs][j])
					r = min(r,rn[rs][j]);
			}
			if (r < INF){
				ln[u][cnt[u]] = ln[ls][i];
				rn[u][cnt[u]] = r;
				cnt[u]++;
			}
		}
	}
}
void build(int u,int l,int r){
	if (l == r){
		cnt[u] = 2;
		ln[u][0] = rn[u][0] = a[l];
		ln[u][1] = rn[u][1] = b[l];
		return;
	}
	int mid = l + r >> 1;
	build(ls,l,mid);
	build(rs,mid + 1,r);
	upd(u);
}
void modify(int u,int l,int r,int pos,cp v){
	if (l == r){
		cnt[u] = 2;
		ln[u][0] = rn[u][0] = v.first;
		ln[u][1] = rn[u][1] = v.second;
		return;
	}
	int mid = l + r >> 1;
	if (mid >= pos) modify(ls,l,mid,pos,v);
	else modify(rs,mid + 1,r,pos,v);
	upd(u);
}
void print(int u,int l,int r){
	if (l == r){
		printf("(%d,%d)  ",ln[u][0],ln[u][1]);
		return;
	}
	int mid = l + r >> 1;
	print(ls,l,mid); print(rs,mid + 1,r);
}
int main(){
	n = read();
	REP(i,n) a[i] = read(),b[i] = read();
	build(1,1,n);
	m = read();
	int c,d;
	while (m--){
		//print(1,1,n); puts("");
		c = read(); d = read();
		modify(1,1,n,c,mp(a[d],b[d]));
		modify(1,1,n,d,mp(a[c],b[c]));
		swap(a[c],a[d]); swap(b[c],b[d]);
		puts(cnt[1] ? "TAK" : "NIE");
	}
	return 0;
}

posted @ 2018-05-28 09:39  Mychael  阅读(202)  评论(0编辑  收藏  举报