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. 开发手记:Linux下更改Oracle表空间大小

    问题:同事反馈我们的测试环境数据库执行SQL和编译PKG非常慢,猜测可能是我们的测试环境数据库的表空间满了,但是我不知道数据库DBA的用户和密码. 步骤1:查看表空间占用情况 SELECT UPPER ...

  2. CF1153F Serval and Bonus Problem FFT

    CF1153F Serval and Bonus Problem 官方的解法是\(O(n ^ 2)\)的,这里给出一个\(O(n \log n)\)的做法. 首先对于长度为\(l\)的线段,显然它的答 ...

  3. python 文本特征提取 CountVectorizer, TfidfVectorizer

    1. TF-IDF概述 TF-IDF(term frequency–inverse document frequency)是一种用于资讯检索与文本挖掘的常用加权技术.TF-IDF是一种统计方法,用以评 ...

  4. 20135316Linux内核学习笔记第八周

    20135316王剑桥<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC 1000029000 一.进程调度与进程调度的时机分析 ...

  5. JS 字符串转换为number

    // '+ "42"' --> + 加上数字字符串可转换成数值 console.log(typeof (+ "42")); // 输出为 number

  6. 5.1 四则运算单元测试j

    由于上个星期请假没上课,这个星期回来才知道作业,时间比较赶,个人能力又不足,作业质量不是很好 Calculator.java import java.util.Scanner; public clas ...

  7. 在web.xml中配置监听器来控制ioc容器生命周期

    5.整合关键-在web.xml中配置监听器来控制ioc容器生命周期 原因: 1.配置的组件太多,需保障单实例 2.项目停止后,ioc容器也需要关掉,降低对内存资源的占用. 项目启动创建容器,项目停止销 ...

  8. Prism6下的MEF:基于微软企业库的Cache

    通常,应用程序可以将那些频繁访问的数据,以及那些需要大量处理时间来创建的数据存储在内存中,从而提高性能.基于微软的企业库,我们的快速创建一个缓存的实现. 新建PrismSample.Infrastru ...

  9. shell脚本--逻辑判断与字符串比较

    涉及到比较和判断的时候,要注意 整数比较使用-lt,-gt,ge等比较运算符,详情参考:整数比较 文件测试使用 -d, -f, -x等运算发,详情参考:文件测试 逻辑判断使用    && ...

  10. shell脚本--文件测试

    文件测试是指测试某一个文件或者目录是否存在 测试文件格式[ 操作符 目录或者文件 ]    注意左括号和操作符之间有一个空格,文件或者目录 与右边的括号之间也有一个空格. -d 测试是否为目录 -e ...