链接:https://www.nowcoder.net/acm/contest/71/E
来源:牛客网

题目描述

有一个长为 n 的数列 A,其中有 m 个限制条件,条件有两种:
1、对于区间 [l,r],其区间元素按位或和等于 x
2、对于区间 [l,r],其区间元素按位与和等于 x
求出一个数列 A,使得满足给定的 m 个条件,保证有解。

输入描述:

  1. 输入第一行两个正整数 n,m,意义如上
    接下来 m 行,每行四个整数 op,l,r,x,表示一组限制
    op = 1 表示是限制 1op = 2 表示是限制 2

输出描述:

  1. 输出仅一行,n 个整数 a

i

  1. 表示数列 A。要求 0 <= a

i

  1. < 10

9

输入例子:
  1. 4 3
  2. 1 1 2 9
  3. 2 3 4 2
  4. 1 2 3 11
输出例子:
  1. 1 9 2 6

-->

示例1

输入

  1. 4 3
  2. 1 1 2 9
  3. 2 3 4 2
  4. 1 2 3 11

输出

  1. 1 9 2 6

备注:

  1. 1<=n,m<=10^5, 1<=l<=r<=n, 0<=x<2^20

题解

差分约束系统,剪枝。

每一位分开考虑,可以列出一系列不等式,只要求出一组可行解。

剪枝:

对于某些位置,在没有跑差分约束系统之前,就可以确定一定是$1$,也就是可以多增加一些不等式,形如$sum[i] - sum[0] >= x$,用来剪枝。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. const int maxn = 1e5 + 10;
  5. int n, m;
  6. int op[maxn], L[maxn], R[maxn], x[maxn];
  7. int h[maxn], v[maxn * 10], w[maxn * 10], nx[maxn * 10];
  8. int sz;
  9. int ans[maxn];
  10.  
  11. int dis[maxn], f[maxn];
  12. int sum[maxn];
  13.  
  14. void init() {
  15. for(int i = 0; i <= n; i ++) {
  16. h[i] = -1;
  17. sum[i] = 0;
  18. }
  19. sz = 0;
  20. }
  21.  
  22. void add(int a, int b, int c) {
  23. //printf("%d -> %d : %d\n", a, b, -c);
  24. v[sz] = b;
  25. w[sz] = -c;
  26. nx[sz] = h[a];
  27. h[a] = sz ++;
  28. }
  29.  
  30. void spfa() {
  31. queue<int> q;
  32. for(int i = 0; i <= n; i ++) {
  33. dis[i] = maxn;
  34. f[i] = 0;
  35. }
  36. dis[0] = 0;
  37. q.push(0);
  38. f[0] = 1;
  39. while(!q.empty()) {
  40. int top = q.front();
  41. q.pop();
  42. f[top] = 0;
  43. for(int i = h[top]; i != -1; i = nx[i]) {
  44. if(dis[top] + w[i] < dis[v[i]]) {
  45. dis[v[i]] = dis[top] + w[i];
  46. if(f[v[i]] == 0) {
  47. f[v[i]] = 1;
  48. q.push(v[i]);
  49. }
  50. }
  51. }
  52. }
  53. }
  54.  
  55. int main() {
  56. scanf("%d%d", &n, &m);
  57. for(int i = 1; i <= m; i ++) {
  58. scanf("%d%d%d%d", &op[i], &L[i], &R[i], &x[i]);
  59. }
  60. for(int t = 0; t < 20; t ++) {
  61. init();
  62. // 0 <= sum[x] - sum[x - 1] <= 1
  63. // ! sum[x] - sum[x - 1] >= 0
  64. // ! sum[x - 1] - sum[x] >= -1
  65. for(int i = 1; i <= n; i ++) {
  66. add(i - 1, i, 0);
  67. add(i, i - 1, -1);
  68. }
  69. for(int i = 1; i <= m; i ++) {
  70. if(op[i] == 1) {
  71. if(x[i] & (1 << t)) {
  72. // [L, R] 至少有一个1
  73. // sum[R] - sum[L - 1] >= 1
  74. add(L[i] - 1, R[i], 1);
  75. } else {
  76. // [L, R] 全为0
  77. // 0 <= sum[R] - sum[L - 1] <= 0
  78. // ! sum[R] - sum[L - 1] >= 0
  79. // ! sum[L - 1] - sum[R] >= 0
  80. add(L[i] - 1, R[i], 0);
  81. add(R[i], L[i] - 1, 0);
  82. }
  83. } else {
  84. if(x[i] & (1 << t)) {
  85. // [L, R] 全为1
  86. // R - L + 1 <= sum[R] - sum[L - 1] <= R - L + 1
  87. // ! sum[R] - sum[L - 1] >= R - L + 1
  88. // ! sum[L - 1] - sum[R] >= -(R - L + 1)
  89. add(L[i] - 1, R[i], R[i] - L[i] + 1);
  90. add(R[i], L[i] - 1, -(R[i] - L[i] + 1));
  91. sum[L[i]] ++;
  92. sum[R[i] + 1] --;
  93. } else {
  94. // [L, R] 不全为1
  95. // 0 <= sum[R] - sum[L - 1] <= R - L
  96. // ! sum[R] - sum[L - 1] >= 0
  97. // ! sum[L - 1] - sum[R] >= L - R
  98. add(L[i] - 1, R[i], 0);
  99. add(R[i], L[i] - 1, L[i] - R[i]);
  100. }
  101. }
  102. }
  103. for(int i = 1; i <= n; i ++) {
  104. sum[i] += sum[i - 1];
  105. }
  106. for(int i = 1; i <= n; i ++) {
  107. if(sum[i]) sum[i] = 1;
  108. }
  109. for(int i = 1; i <= n; i ++) {
  110. sum[i] += sum[i - 1];
  111. add(0, i, sum[i]);
  112. }
  113. spfa();
  114. for(int i = 1; i <= n; i ++) {
  115. dis[i] = -dis[i];
  116. }
  117. for(int i = n; i >= 1; i --) {
  118. dis[i] = dis[i] - dis[i - 1];
  119. }
  120. for(int i = 1; i <= n; i ++) {
  121. ans[i] = ans[i] + dis[i] * (1 << t);
  122. }
  123. }
  124. for(int i = 1; i <= n; i ++) {
  125. printf("%d", ans[i]);
  126. if(i < n) printf(" ");
  127. else printf("\n");
  128. }
  129. return 0;
  130. }
  131.  
  132. /*
  133. v[j] - v[i] >= k, 问v[t] - v[s]最小值
  134. 建边 i -> j, 权值为k, s到t的最长路就是答案
  135. */

Wannafly挑战赛9 E - 组一组的更多相关文章

  1. wannafly 挑战赛9 E 组一组 (差分约束)

    链接:https://www.nowcoder.com/acm/contest/71/E 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 65536K,其他语言131072K Spec ...

  2. Wannafly挑战赛25游记

    Wannafly挑战赛25游记 A - 因子 题目大意: 令\(x=n!(n\le10^{12})\),给定一大于\(1\)的正整数\(p(p\le10000)\)求一个\(k\)使得\(p^k|x\ ...

  3. 【Wannafly挑战赛4】F 线路规划 倍增+Kruskal+归并

    [Wannafly挑战赛4]F 线路规划 题目描述 Q国的监察院是一个神秘的组织.这个组织掌握了整个帝国的地下力量,监察着Q国的每一个人.监察院一共有N个成员,每一个成员都有且仅有1个直接上司,而他只 ...

  4. 【Wannafly挑战赛24E】旅行

    [Wannafly挑战赛24E]旅行 题面 牛客 题解 首先有一个非常显然的\(dp\):我们直接把\(s\rightarrow t\)的路径抠出来然后设\(f_{i,j}\)表示到第\(i\)个点, ...

  5. Wannafly挑战赛13 zzf的好矩阵 题解 答案解释

    Wannafly挑战赛13 zzf的好矩阵 题解 文章目录 Wannafly挑战赛13 zzf的好矩阵 题解 分析 结论1 结论2 结论3 C数组对应带子说明 空白长度论述 后续黑色长度论述 能&qu ...

  6. 【Nowcoder71E】组一组(差分约束,最短路)

    [Nowcoder71E]组一组(差分约束,最短路) 题面 Nowcoder 题解 看到二进制显然就直接拆位,那么区间的按位或和按位与转成前缀和之后,可以写成两个前缀和的值的差的大小关系,那么直接差分 ...

  7. Wannafly挑战赛27

    Wannafly挑战赛27 我打的第一场$Wannafly$是第25场,$T2$竟然出了一个几何题?而且还把我好不容易升上绿的$Rating$又降回了蓝名...之后再不敢打$Wannafly$了. 由 ...

  8. Wannafly 挑战赛 19 参考题解

    这一次的 Wannafly 挑战赛题目是我出的,除了第一题,剩余的题目好像对大部分算法竞赛者来说好像都不是特别友好,但是个人感觉题目质量还是过得去的,下面是题目链接以及题解. [题目链接] Wanna ...

  9. Wannafly挑战赛21A

    题目链接 Wannafly挑战赛21A 题解 代码 #include <cstdio> #include <cmath> #define MAX 1000005 #define ...

随机推荐

  1. linux下各个目录里面都装了什么

    文章来源:http://blog.csdn.net/sunstars2009918/article/details/7038772 搞电脑的人总想知道自己的系统里到底有些什么东西,于是我就在Linux ...

  2. Go语言学习笔记(3)——分支、循环结构

    1 条件语句: if, else if, else   特殊用法:判断num是奇是偶:其中局部变量num只能在该if...else语句中使用! if num := 10; num % 2 == 0 { ...

  3. 钉钉h5项目实战|仿钉钉聊天|h5移动端钉钉案例

    最近一直着手开发h5仿钉钉项目,使用到了h5+css3+zepto+wcPop2等技术进行开发,实现了消息.表情.动图发送,仿QQ多人拼合图像,可以选择本地图片,并可以图片.视频预览,仿微信发红包及打 ...

  4. J07-Java IO流总结七 《 InputStreamReader和OutputStreamWriter 》

    前面在介绍FileReader和FileWriter的时候有说到,FileReader的读取字符功能,以及FileWriter的写出字符的功能,都不是它们自己实现的,而是,它们分别继承了InputSt ...

  5. 剑指offer二十二之从上往下打印二叉树

    一.题目 从上往下打印出二叉树的每个节点,同层节点从左至右打印. 二.思路 二叉树的层次遍历,可以借助队列实现.具体思路详见注释. 三.代码 import java.util.ArrayList; i ...

  6. Docker笔记:常用命令汇总

    Docker常用命令汇总 启动服务 [root@localhost ~]# service docker start Redirecting to /bin/systemctl start docke ...

  7. tomcat启动(三)Catalina简要分析

    上篇解析Bootstrap到 daemon.setAwait(true); daemon.load(args); daemon.start(); 这三个方法实际是反射调用org.apache.cata ...

  8. Linux发行版,分类,CentOS下载

    目录 Debian 系(dpkg) 1. 包管理 2. 发行版 Red Hat 系(rpm) 1. 包管理 2. 发行版 其他发行版   Debian 系(dpkg) 1. 包管理 包管理器:dpkg ...

  9. 进击Node.js基础(二)

    一.一个牛逼闪闪的知识点Promise npm install bluebird 二.Promise实例 ball.html <!doctype> <!DOCTYPE html> ...

  10. 链式编程:遇到多个构造器参数(Constructor Parameters)时要考虑用构建器(Builder)

    public class NutritionFacts { private final int servingSize; private final int servings; private fin ...