首页 > 其他分享 >Solution - Atcoder ABC155F Perils in Parallel

Solution - Atcoder ABC155F Perils in Parallel

时间:2024-08-13 21:06:13浏览次数:9  
标签:pre Atcoder int 可以 Solution 取反 maxn ABC155F 考虑

首先可以按 \(a_i\) 排序,对于区间 \([l_i, r_i]\) 可以通过二分确定实际影响到的 \(b_i\) 的区间。

考虑到区间 \(i\in [l, r]\) 的 \(b_i\) 都取反影响到的元素过多,考虑去减少影响到的元素。

于是可以想到令 \(c_i = b_i \oplus b_{i - 1}\),那么对于区间 \([l, r]\) 操作实际影响到的就只会有 \(c_l, c_{r + 1}\) 了。

此时相当于是 \(l, r + 1\) 可以共同取反,于是可以考虑连边 \((l, r + 1)\)。

此时就相当于是给定了一个图和 \(c_{1\sim n + 1}\),每次可以将一条边的两个端点的 \(c_i\) 取反,要将 \(c_{1\sim n + 1}\) 调整至目标状态全 \(0\)(因为有 \(b_0 = 0\),可以递推得到 \(b_{1\sim n + 1} = 0\))。

显然对于这个图可以分成不同的连通块,因为每个连通块间互相独立。
但是对于一张图来说,边太多也太杂,不好处理,所以继续考虑减少无用边。

考虑对于这个图跑出来一个生成树,那么可以发现操作不在生成树上的边可以通过操作树上两个端点之间路径上的所有边代替。
那么这个图就被缩减成一棵树了。

接下来考虑对这棵树来操作。
这部分是简单的,考虑随意钦定一个根,从叶子节点往上递推,这是因为此时连向儿子的边都已经确定了,只剩与父亲的连边还可以进行调整。
如果操作完后根的点权为 \(1\),因为根没有可以进行调整的边,一定无解。

若有解,上面的过程就已经确定了要操作的边了。

时间复杂度 \(\mathcal{O}((n + m)\log n)\)。

#include<bits/stdc++.h>
#define fi first
#define se second
const int maxn = 2e5 + 10;
using pii = std::pair<int, int>;
pii a[maxn];
int pre[maxn];
std::vector<pii> to[maxn];
int vis[maxn], ans[maxn];
void dfs(int u, int fa = 0, int fl = 0) {
   vis[u] = 1;
   for (auto [v, id] : to[u]) {
      if (vis[v]) continue;
      dfs(v, u, id);
   }
   if (pre[u] && ! fa) {
      puts("-1");
      exit(0);
   }
   ans[fl] = pre[u], pre[fa] ^= pre[u];
}
int main() {
   int n, m; scanf("%d%d", &n, &m);
   for (int i = 1; i <= n; i++)
      scanf("%d%d", &a[i].fi, &a[i].se);
   std::sort(a + 1, a + n + 1);
   a[n + 1].fi = 2e9;
   for (int i = 1; i <= n + 1; i++)
      pre[i] = a[i - 1].se ^ a[i].se;
   for (int i = 1; i <= m; i++) {
      int l, r; scanf("%d%d", &l, &r);
      l = std::lower_bound(a + 1, a + n + 2, pii{l, 0}) - a;
      r = std::lower_bound(a + 1, a + n + 2, pii{r + 1, 0}) - a;
      to[l].emplace_back(r, i), to[r].emplace_back(l, i);
   }
   for (int i = 1; i <= n + 1; i++)
      if (! vis[i])
         dfs(i);
   std::vector<int> ANS;
   for (int i = 1; i <= m; i++)
      if (ans[i])
         ANS.push_back(i);
   printf("%zu\n", ANS.size());
   for (int x : ANS)
      printf("%d ", x);
   return 0;
}

标签:pre,Atcoder,int,可以,Solution,取反,maxn,ABC155F,考虑
From: https://www.cnblogs.com/rizynvu/p/18357682

相关文章

  • Atcoder nomura2020F Sorting Game
    首先考虑如果固定了\(a\),如何判定这个\(a\)是否能被排序。如果存在\(a_i>a_j(i<j)\),那么\(a_i\)肯定要交换到\(a_j\)后面,那么就肯定会交换\(a_i,a_j\)。于是合法条件就是如果存在\(a_i>a_j(i<j)\),那么\(a_i,a_j\)只相差一个二进制位。那就还能知道此时一......
  • AtCoder Regular Contest 041 D 辺彩色
    洛谷传送门AtCoder传送门比较有意思的小清新题。第一步是时光倒流,看成是每次经过一条未被访问过的边才染色。奇偶相关容易想到二分图。发现若有一个黑白交替的奇环(即从一个点开始遍历完整个环得到的颜色序列是黑白交替地),那我们可以先染完这个环。又因为它是奇环,所以我们遍历......
  • AtCoder ABC 366题解
    前言本文部分思路来自于网络,仅供参考。A-Election2题目大意给定两个市长候选人的票数,求结果是否已经确定。解题思路如果剩下的人全部投票给票少的人票少的人也不能赢,则结果就已经确定了。code#include<bits/stdc++.h>usingnamespacestd;intmain(){intn,t,......
  • AtCoder Beginner Contest 366
    A-Election2(abc366A)题目大意\(n\)张票,目前投了\(t\)给高桥,\(a\)给青木。问剩余票随便分配,是否都是一个结局。解题思路考虑最好情况,即剩下票全部投给当前票少的,看看能不能超过对方,会则结局会变,否则不会变。神奇的代码#include<bits/stdc++.h>usingnamespaces......
  • AtCoder Beginner Contest 366 C,D题解
    C-BallsandBagQuery题解题意没什么好说的,给出q次查询,进行求解思路很简单的一道题,但这篇题解的作用是引出unordered_set,这个东西的作用类似set,但没有排序,相当于哈希。unordered_set有几种操作,接下来介绍三种insert,没什么可说的,普通的插入erase,进行弹出size,返回大......
  • G - AtCoder Office
    G-AtCoderOfficeProblemStatement$N$peopleworkattheAtCoderoffice.Theofficekeepsrecordsofentriesandexits,andtherehavebeen$M$entriesandexitssincetherecordsbegan.The$i$-th$(1\leqi\leqM)$recordisrepresentedbyapairof......
  • AtCoder Regular Contest 100 F Colorful Sequences
    洛谷传送门AtCoder传送门比较有趣的一个题。考虑一个弱化版,算colorful序列个数。有一个\(O(nK)\)的dp,大概就是设\(f_{i,j}\)为考虑到第\(i\)个数,当前最长互不相同后缀长度为\(j\)。转移考虑若往后面填一个在这\(j\)个数以外的数就能使\(j\getsj+1\),因此\(......
  • 杂题 Solution 速通 #1
    [ICPC2021NanjingR]AncientMagicCircleinTeyvat设\(f_x\)表示钦定至少有\(x\)条边的四元子图个数,由容斥我们有一条边都没有的子图个数是\(f_0-f_1+f_2-f_3+f_4-f_5+f_6\),而所有边都有的个数就是\(f_6\)。作差之后只需要求\(f_0,f_1,f_2,f_3,f_4,f_5\)。子图计数只......
  • 【题解】Solution Set - NOIP2024集训Day2 线段树
    【题解】SolutionSet-NOIP2024集训Day2线段树https://www.becoder.com.cn/contest/5431「CF1149C」TreeGenerator™结论:对于括号序列的一个子段,删去所有的匹配括号之后,剩下的不匹配的括号,按顺序构成树上的一条路径。Why?从括号序列的构造出发。每次(相当于开始遍历......
  • 【题解】Solution Set - NOIP2024集训Day1 数据结构
    【题解】SolutionSet-NOIP2024集训Day1数据结构https://www.becoder.com.cn/contest/5429「CF1428F」FruitSequences线段树是可以维护区间最长子段的1。记固定右端点在\(i\),的答案为\(f_i\)。那么:\(a_i=0\),\(f_i=f_{i-1}\);\(a_i=1\),打一个单调栈维护所有的最长子......