3526: [Poi2014]Card

Time Limit: 25 Sec  Memory Limit: 64 MB
Submit: 267  Solved: 191
[Submit][Status][Discuss]

Description

有n张卡片在桌上一字排开,每张卡片上有两个数,第i张卡片上,正面的数为a[i],反面的数为b[i]。现在,有m个熊孩子来破坏你的卡片了!
第i个熊孩子会交换c[i]和d[i]两个位置上的卡片。
每个熊孩子捣乱后,你都需要判断,通过任意翻转卡片(把正面变为反面或把反面变成正面,但不能改变卡片的位置),能否让卡片正面上的数从左到右单调不降。

Input

第一行一个n。
接下来n行,每行两个数a[i],b[i]。
接下来一行一个m。
接下来m行,每行两个数c[i],d[i]。

Output

m行,每行对应一个答案。如果能成功,输出TAK,否则输出NIE。

Sample Input

4
2 5
3 4
6 3
2 7
2
3 4
1 3

Sample Output

NIE
TAK

HINT

【样例解释】

交换3和4后,卡片序列为(2,5) (3,4) (2,7) (6,3),不能成功。

交换1和3后,卡片序列为(2,7) (3,4) (2,5) (6,3),翻转第3张卡片,卡片的正面为2,3,5,6,可以成功。

【数据范围】

n≤200000,m≤1000000,0≤a[i],b[i]≤10000000,1≤c[i],d[i]≤n.

Source

[Submit][Status][Discuss]

好有趣的一道题,老早就写过,现在又重新写一遍,强行缩代码,2333.

就是用线段树,维护每个区间,如果选取区间左端较小值,右端能以什么结尾;如果选取区间左端较大值,右端能以什么结尾。

 #include<cstdio>
#define mxn 200005
#define siz 800005
#define mxm 1000005
#define swap(a,b) a^=b^=a^=b
int n,m,a[mxn],b[mxn],c,d,A[siz],B[siz];
void update(int t,int l,int r,int d,int ls,int rs){
A[t]=B[t]=;
if((A[ls]==&&a[d]<=b[d+])||(A[ls]==&&b[d]<=b[d+]))A[t]=B[rs];
if((A[ls]==&&a[d]<=a[d+])||(A[ls]==&&b[d]<=a[d+]))A[t]=A[rs];
if((B[ls]==&&a[d]<=b[d+])||(B[ls]==&&b[d]<=b[d+]))B[t]=B[rs];
if((B[ls]==&&a[d]<=a[d+])||(B[ls]==&&b[d]<=a[d+]))B[t]=A[rs];
}
void build(int t,int l,int r){
if(l==r){A[t]=;B[t]=;return;}
int d=(l+r)>>,ls=t<<,rs=t<<|;
build(ls,l,d),build(rs,d+,r);
update(t,l,r,d,ls,rs);
}
void rebuild(int t,int l,int r,int p){
if(l==r){A[t]=;B[t]=;return;}
int d=(l+r)>>,ls=t<<,rs=t<<|;
if(p<=d)rebuild(ls,l,d,p);else rebuild(rs,d+,r,p);
update(t,l,r,d,ls,rs);
}
main(){
scanf("%d",&n);
for(int i=;i<=n;++i)scanf("%d%d",a+i,b+i);
for(int i=;i<=n;++i)if(a[i]>b[i])swap(a[i],b[i]);
build(,,n);
scanf("%d",&m);
for(int i=;i<=m;++i)scanf("%d%d",&c,&d),puts((swap(a[c],a[d]),swap(b[c],b[d]),rebuild(,,n,c),rebuild(,,n,d),A[])?"TAK":"NIE");
}

原来的代码看起来好冗长的样子……

 #include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm> using namespace std; const int N = ;
const int M = ; int n, m; struct card
{
int a, b; card(void) {};
card(int _a, int _b)
{
a = min(_a, _b);
b = max(_a, _b);
}
}c[N]; struct node
{
int lt, rt;
int valA, valB;
}tree[N << ]; void buildTree(int p, int l, int r)
{
node &t = tree[p]; t.lt = l, t.rt = r; if (t.lt == t.rt)
{
t.valA = ;
t.valB = ; return;
} int mid = (t.lt + t.rt) >> ; buildTree(p << , t.lt, mid);
buildTree(p << | , mid + , t.rt); t.valA = t.valB = ; switch (tree[p << ].valA)
{
case :
if (c[mid].a <= c[mid + ].b)
t.valA = tree[p << | ].valB;
if (c[mid].a <= c[mid + ].a)
t.valA = tree[p << | ].valA;
break;
case :
if (c[mid].b <= c[mid + ].b)
t.valA = tree[p << | ].valB;
if (c[mid].b <= c[mid + ].a)
t.valA = tree[p << | ].valA;
break;
} switch (tree[p << ].valB)
{
case :
if (c[mid].a <= c[mid + ].b)
t.valB = tree[p << | ].valB;
if (c[mid].a <= c[mid + ].a)
t.valB = tree[p << | ].valA;
break;
case :
if (c[mid].b <= c[mid + ].b)
t.valB = tree[p << | ].valB;
if (c[mid].b <= c[mid + ].a)
t.valB = tree[p << | ].valA;
break;
}
} void change(int p, int pos)
{
node &t = tree[p]; if (t.lt == t.rt)
{
t.valA = ;
t.valB = ; return;
} int mid = (t.lt + t.rt) >> ; if (pos <= mid)
change(p << , pos);
else
change(p << | , pos); t.valA = t.valB = ; switch (tree[p << ].valA)
{
case :
if (c[mid].a <= c[mid + ].b)
t.valA = tree[p << | ].valB;
if (c[mid].a <= c[mid + ].a)
t.valA = tree[p << | ].valA;
break;
case :
if (c[mid].b <= c[mid + ].b)
t.valA = tree[p << | ].valB;
if (c[mid].b <= c[mid + ].a)
t.valA = tree[p << | ].valA;
break;
} switch (tree[p << ].valB)
{
case :
if (c[mid].a <= c[mid + ].b)
t.valB = tree[p << | ].valB;
if (c[mid].a <= c[mid + ].a)
t.valB = tree[p << | ].valA;
break;
case :
if (c[mid].b <= c[mid + ].b)
t.valB = tree[p << | ].valB;
if (c[mid].b <= c[mid + ].a)
t.valB = tree[p << | ].valA;
break;
}
} signed main(void)
{
scanf("%d", &n); for (int i = , a, b; i <= n; ++i)
scanf("%d%d", &a, &b), c[i] = card(a, b); buildTree(, , n); scanf("%d", &m); for (int i = , a, b; i <= m; ++i)
{
scanf("%d%d", &a, &b); swap(c[a], c[b]); change(, a);
change(, b); if (tree[].valA)
puts("TAK");
else
puts("NIE");
}
}

@Author: YouSiki

BZOJ 3526: [Poi2014]Card的更多相关文章

  1. 【BZOJ】3526: [Poi2014]Card

    题意 \(n(n \le 200000)\)张卡片,正反有两个数\(a[i], b[i]\).\(m(m \le 1000000)\)次操作,每次交换\(c[i].d[i]\)位置上的卡片.每一次操作 ...

  2. 【刷题】BZOJ 4543 [POI2014]Hotel加强版

    Description 同OJ3522 数据范围:n<=100000 Solution dp的设计见[刷题]BZOJ 3522 [Poi2014]Hotel 然后发现dp的第二维与深度有关,于是 ...

  3. 【BZOJ3526】[Poi2014]Card 线段树

    [BZOJ3526][Poi2014]Card Description 有n张卡片在桌上一字排开,每张卡片上有两个数,第i张卡片上,正面的数为a[i],反面的数为b[i].现在,有m个熊孩子来破坏你的 ...

  4. bzoj3526[Poi2014]Card*

    bzoj3526[Poi2014]Card 题意: 有n张卡片在桌上一字排开,每张卡片上有两个数,第i张卡片上,正面的数为a[i],反面的数为b[i].有m个操作,第i个操作会交换c[i]和d[i]两 ...

  5. 主席树||可持久化线段树||BZOJ 3524: [Poi2014]Couriers||BZOJ 2223: [Coci 2009]PATULJCI||Luogu P3567 [POI2014]KUR-Couriers

    题目:[POI2014]KUR-Couriers 题解: 要求出现次数大于(R-L+1)/2的数,这样的数最多只有一个.我们对序列做主席树,每个节点记录出现的次数和(sum).(这里忽略版本差值问题) ...

  6. BZOJ 3524: [Poi2014]Couriers [主席树]

    3524: [Poi2014]Couriers Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1892  Solved: 683[Submit][St ...

  7. BZOJ 3524: [Poi2014]Couriers

    3524: [Poi2014]Couriers Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1905  Solved: 691[Submit][St ...

  8. Bzoj 3831 [Poi2014]Little Bird

    3831: [Poi2014]Little Bird Time Limit: 20 Sec Memory Limit: 128 MB Submit: 310 Solved: 186 [Submit][ ...

  9. [BZOJ 3829][POI2014] FarmCraft

    先贴一波题面... 3829: [Poi2014]FarmCraft Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 421  Solved: 197[ ...

随机推荐

  1. 事件(event)

    事件概述 委托是一种类型可以被实例化,而事件可以看作将多播委托进行封装的一个对象成员(简化委托调用列表增加和删除方法)但并非特殊的委托,保护订阅互不影响. 基础事件(event) 在.Net中声明事件 ...

  2. item 7:当创建对象的时候,区分()和{}的使用

    本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 从不同的角度来看,在C++11中,对象初始化拥有多种语法选择,这体 ...

  3. 安装zkpython出错

    pip3 install zkpython==0.4.2 提示:zookeeper.c:20:23: 致命错误:zookeeper.h:没有那个文件或目录 解决: 1.是否安装python-devel ...

  4. 复审Partner

    复审代码后,发现了一些问题: 首先说优点:代码十分工整,很清晰,各种类易于理解,逻辑上很通顺. 基本实现了代码功能,输出正确. 发现的缺点:对于文件后缀的识别有点问题,不能识别所需求的所有文件,只有一 ...

  5. 个人博客作业Week 3 ——微软必应词典客户端

    产品:必应词典客户端 (http://bing.msn.cn/dict/)必应词典有PC,Win8/10, Windows Phone,iPhone,Android,iPad 客户端 选择客户端为:i ...

  6. 《Linux内核分析》第八周

    <Linux内核分析>第八周 PART ONE 知识点总结 一.进程切换的关键代码switch_to 1.进程调度与进程调度的时机 (1)进程分类: I/O型(执行块,频繁) CPU型(大 ...

  7. 个人git链接和git学习心得总结

    个人git链接和git学习心得总结 个人git链接: https://github.com/hanzhaoyan Git 是 Linux 的创始人 Linus Torvalds 开发的开源和免费的版本 ...

  8. 自己实现数据结构系列一---ArrayList

    1.先上代码: public class ArrayList<E> { private E[] data; private int size; /** * 构造方法,初始化容量capaci ...

  9. Windows samba history

    https://blogs.technet.microsoft.com/josebda/2013/10/02/windows-server-2012-r2-which-version-of-the-s ...

  10. WIN10快捷键

    WIN10快捷键 多桌面切换:WIN + CTRL +  ←/→ 桌面横竖屏转向:ALT + CTRL +  ←/→