题解:P3569 [POI2014] KAR-Cards

2024-06-22 13:12
文章标签 题解 cards poi2014 p3569 kar

本文主要是介绍题解:P3569 [POI2014] KAR-Cards,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题意

n n n 个元素,第 i i i 个元素有两个权值 a i a_i ai b i b_i bi;有 m m m 次操作,每次操作会交换两个元素的位置,且都需要回答:是否存在一种方案,使得每个元素各选择一个权值后,组成的序列从左到右单调不降。

解法

完全可以把交换操作看作两次单点修改,每次只需要考虑一个元素的变化对答案的影响即可。对于一个区间中的元素,显然开头的数越小,该区间能够单调不降的概率越大。不妨设 a i < b i a_i<b_i ai<bi,考虑线段树,对于区间 [ L , R ] [L,R] [L,R] 我们维护两个值:

  • L L L 个元素选择 a L a_L aL,第 R R R 个元素尽量小的情况下,第 R R R 个元素会选择 a R a_R aR b R b_R bR 或无解;
  • L L L 个元素选择 b L b_L bL,第 R R R 个元素尽量小的情况下,第 R R R 个元素会选择 a R a_R aR b R b_R bR​ 或无解。

合并两个相邻区间的信息时,我们枚举左区间 [ L , R ] [L,R] [L,R] 选择 a L a_L aL b L b_L bL、右区间 [ L ′ , R ′ ] [L',R'] [L,R] 选择 a L ′ a_{L'} aL b L ′ b_{L'} bL,判断 a R < b L ′ a_R<b_{L'} aR<bL 是否成立(已经保证小区间内单调不降或无解);最后贪心地让合并后的区间 [ L , R ′ ] [L,R'] [L,R] 末尾选择的数尽可能小。总时间复杂度 O ( n + m log ⁡ n ) O(n+m\log n) O(n+mlogn)

实现

开两个数组 x , y x,y x,y 维护这两个值(直接存末尾卡牌选择的值)。在建树、修改的时候用子区间信息进行更新。令该区间为 [ l , r ] [l,r] [l,r],两个子区间的编号为 L , R L,R L,R(以 m i d = ⌊ l + r 2 ⌋ mid=\lfloor\cfrac{l+r}{2}\rfloor mid=2l+r 为界),我们枚举用 x [ L ] x[L] x[L] 还是 y [ L ] y[L] y[L] 连接两个子区间、用 x [ R ] x[R] x[R] 还是 y [ R ] y[R] y[R] 作为结尾,并且优先考虑使用较小的 x [ R ] x[R] x[R] 作为结尾。我们在修改的时候顺便更换 a , b a,b a,b 数组,则只需判断 x [ L ] x[L] x[L] 或者 y [ L ] y[L] y[L] 是否不大于 a [ m i d + 1 ] a[mid+1] a[mid+1] 或者 b [ m i d + 1 ] b[mid+1] b[mid+1](共 4 4 4 种)。最终该区间的末尾取决于 R R R 子区间末尾的选择。注意处理好无解的情况。

代码

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
struct Card { int A,B; } a[maxn];
int x[maxn << 2], y[maxn << 2]; // x 第一张小,y 第一张大
#define lson l,mid,rt << 1
#define rson mid + 1,r,rt << 1 | 1
const int inf = 1e7 + 5;
void update(int l,int r,int rt) {int mid = l + r >> 1;int L = rt << 1, R = rt << 1 | 1; // 两个子区间的编号x[rt] = y[rt] = inf;// 分类讨论if (x[L] <= a[mid + 1].A) x[rt] = x[R];else if (x[L] <= a[mid + 1].B) x[rt] = y[R];if (y[L] <= a[mid + 1].A) y[rt] = x[R];else if (y[L] <= a[mid + 1].B) y[rt] = y[R];
}
void build(int l,int r,int rt) {if (l == r) return x[rt] = a[l].A, y[rt] = a[l].B, void(0);int mid = l + r >> 1;build(lson); build(rson); update(l,r,rt);
}
int now;
void modify(int l,int r,int rt,Card k) {if (l == r) return x[rt] = k.A, y[rt] = k.B, void(0);int mid = l + r >> 1;if (now <= mid) modify(lson,k);else modify(rson,k);update(l,r,rt);
}
int n,m;
int main() {scanf("%d",&n);for (int i = 1;i <= n;i ++) {scanf("%d%d",&a[i].A,&a[i].B);if (a[i].A > a[i].B)swap(a[i].A,a[i].B);}build(1,n,1);scanf("%d",&m);for (int i = 1,u,v;i <= m;i ++) {scanf("%d%d",&u,&v);swap(a[u],a[v]);now = u; modify(1,n,1,a[u]);now = v; modify(1,n,1,a[v]);puts(x[1] < inf || y[1] < inf ? "TAK" : "NIE");}return 0;
}

这篇关于题解:P3569 [POI2014] KAR-Cards的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1084381

相关文章

LeetCode11. 盛最多水的容器题解

LeetCode11. 盛最多水的容器题解 题目链接: https://leetcode.cn/problems/container-with-most-water 示例 思路 暴力解法 定住一个柱子不动,然后用其他柱子与其围住面积,取最大值。 代码如下: public int maxArea1(int[] height) {int n = height.length;int

LeetCode:经典题之141、142 题解及延伸

系列目录 88.合并两个有序数组 52.螺旋数组 567.字符串的排列 643.子数组最大平均数 150.逆波兰表达式 61.旋转链表 160.相交链表 83.删除排序链表中的重复元素 389.找不同 1491.去掉最低工资和最高工资后的工资平均值 896.单调序列 206.反转链表 92.反转链表II 141.环形链表 142.环型链表 目录 系列目录141. 环形链表常量因子 1

C语言 | Leetcode C语言题解之第188题买卖股票的最佳时机IV

题目: 题解: int maxProfit(int k, int* prices, int pricesSize) {int n = pricesSize;if (n == 0) {return 0;}k = fmin(k, n / 2);int buy[k + 1], sell[k + 1];memset(buy, 0, sizeof(buy));memset(sell, 0, size

6月21日训练 (东北林业大学)(个人题解)

前言:   这次训练是大一大二一起参加的训练,总体来说难度是有的,我和队友在比赛时间内就写出了四道题,之后陆陆续续又补了了三道题,还有一道题看了学长题解后感觉有点超出我的能力范围了,就留给以后的自己吧。话不多说,上正文。 正文:   Problem:A 幸运数字: #include <bits/stdc++.h>using namespace std;int sum,ans;in

LeetCode:经典题之389 题解与延伸

系列目录 88.合并两个有序数组 52.螺旋数组 567.字符串的排列 643.子数组最大平均数 150.逆波兰表达式 61.旋转链表 160.相交链表 83.删除排序链表中的重复元素 389.找不同 1491.去掉最低工资和最高工资后的工资平均值 896.单调序列 206.反转链表 92.反转链表II 141.环形链表 142.环型链表 目录 系列目录389.找不同哈希表

Google Code Jam 2014(附官方题解)

2014年Google编程挑战赛 Problem A. Magic Trick Confused? Read the quick-start guide. Small input 6 points You have solved this input set. Note: To advance to the next rounds, you will need to s

Codeforces April Fools Day Contest 2014(附官方题解)

Codeforces2014年愚人节的坑题。。。但还是感觉挺好玩的。。。 A. The Great Game time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Two teams mee

【华东南AWDP】第十七届全国大学生信息安全竞赛 CISCN 2024 创新实践能力赛区域赛 部分题解WP

前言:这次区域赛AWDP安恒作为支持,赛制风格遵循安恒,一小时check一次。室温35°在室内坐了8小时,午饭是藿香正气水拌冰水。这场总体下来中规中矩吧。 WEB-welcome-BREAK Ctrl+U拿到flag WEB-submit-BREAK 文件上传,简单绕过 绕过就两个,一个MIMA头,一个等号换php(短标签) WEB-submit-FIX 修两个点,一个是

C语言 | Leetcode C语言题解之第174题地下城游戏

题目: 题解: int calculateMinimumHP(int** dungeon, int dungeonSize, int* dungeonColSize) {int n = dungeonSize, m = dungeonColSize[0];int dp[n + 1][m + 1];memset(dp, 0x3f, sizeof(dp));dp[n][m - 1] = dp[

Python | Leetcode Python题解之第174题地下城游戏

题目: 题解: class Solution:def calculateMinimumHP(self, dungeon: List[List[int]]) -> int:n, m = len(dungeon), len(dungeon[0])BIG = 10**9dp = [[BIG] * (m + 1) for _ in range(n + 1)]dp[n][m - 1] = dp[n