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

题目描述

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

输入描述:

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

输出描述:

输出仅一行,n 个整数 a

i

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

i

 < 10

9

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

-->

示例1

输入

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

输出

1 9 2 6

备注:

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

题解

差分约束系统,剪枝。

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

剪枝:

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

#include <bits/stdc++.h>
using namespace std; const int maxn = 1e5 + 10;
int n, m;
int op[maxn], L[maxn], R[maxn], x[maxn];
int h[maxn], v[maxn * 10], w[maxn * 10], nx[maxn * 10];
int sz;
int ans[maxn]; int dis[maxn], f[maxn];
int sum[maxn]; void init() {
for(int i = 0; i <= n; i ++) {
h[i] = -1;
sum[i] = 0;
}
sz = 0;
} void add(int a, int b, int c) {
//printf("%d -> %d : %d\n", a, b, -c);
v[sz] = b;
w[sz] = -c;
nx[sz] = h[a];
h[a] = sz ++;
} void spfa() {
queue<int> q;
for(int i = 0; i <= n; i ++) {
dis[i] = maxn;
f[i] = 0;
}
dis[0] = 0;
q.push(0);
f[0] = 1;
while(!q.empty()) {
int top = q.front();
q.pop();
f[top] = 0;
for(int i = h[top]; i != -1; i = nx[i]) {
if(dis[top] + w[i] < dis[v[i]]) {
dis[v[i]] = dis[top] + w[i];
if(f[v[i]] == 0) {
f[v[i]] = 1;
q.push(v[i]);
}
}
}
}
} int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i ++) {
scanf("%d%d%d%d", &op[i], &L[i], &R[i], &x[i]);
}
for(int t = 0; t < 20; t ++) {
init();
// 0 <= sum[x] - sum[x - 1] <= 1
// ! sum[x] - sum[x - 1] >= 0
// ! sum[x - 1] - sum[x] >= -1
for(int i = 1; i <= n; i ++) {
add(i - 1, i, 0);
add(i, i - 1, -1);
}
for(int i = 1; i <= m; i ++) {
if(op[i] == 1) {
if(x[i] & (1 << t)) {
// [L, R] 至少有一个1
// sum[R] - sum[L - 1] >= 1
add(L[i] - 1, R[i], 1);
} else {
// [L, R] 全为0
// 0 <= sum[R] - sum[L - 1] <= 0
// ! sum[R] - sum[L - 1] >= 0
// ! sum[L - 1] - sum[R] >= 0
add(L[i] - 1, R[i], 0);
add(R[i], L[i] - 1, 0);
}
} else {
if(x[i] & (1 << t)) {
// [L, R] 全为1
// R - L + 1 <= sum[R] - sum[L - 1] <= R - L + 1
// ! sum[R] - sum[L - 1] >= R - L + 1
// ! sum[L - 1] - sum[R] >= -(R - L + 1)
add(L[i] - 1, R[i], R[i] - L[i] + 1);
add(R[i], L[i] - 1, -(R[i] - L[i] + 1));
sum[L[i]] ++;
sum[R[i] + 1] --;
} else {
// [L, R] 不全为1
// 0 <= sum[R] - sum[L - 1] <= R - L
// ! sum[R] - sum[L - 1] >= 0
// ! sum[L - 1] - sum[R] >= L - R
add(L[i] - 1, R[i], 0);
add(R[i], L[i] - 1, L[i] - R[i]);
}
}
}
for(int i = 1; i <= n; i ++) {
sum[i] += sum[i - 1];
}
for(int i = 1; i <= n; i ++) {
if(sum[i]) sum[i] = 1;
}
for(int i = 1; i <= n; i ++) {
sum[i] += sum[i - 1];
add(0, i, sum[i]);
}
spfa();
for(int i = 1; i <= n; i ++) {
dis[i] = -dis[i];
}
for(int i = n; i >= 1; i --) {
dis[i] = dis[i] - dis[i - 1];
}
for(int i = 1; i <= n; i ++) {
ans[i] = ans[i] + dis[i] * (1 << t);
}
}
for(int i = 1; i <= n; i ++) {
printf("%d", ans[i]);
if(i < n) printf(" ");
else printf("\n");
}
return 0;
} /*
v[j] - v[i] >= k, 问v[t] - v[s]最小值
建边 i -> j, 权值为k, s到t的最长路就是答案
*/

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. webpack快速入门——处理HTML中的图片

    在webpack中是不喜欢你使用标签<img>来引入图片的,但是我们作前端的人特别热衷于这种写法, 国人也为此开发了一个:html-withimg-loader.他可以很好的处理我们在ht ...

  2. 使用SecureCRT的SFTP传输文件

    使用SecureCRT的SFTP传输文件 使用 FileZilla 上传项目更新,因为软件缓存没处理好,三个文件花了三个小时~~ 找一种缓存干扰最小的方式上传文件. 1.在使用 SecureCRT 连 ...

  3. 移动端 实现ul横向滚动条

    ul { display: flex; width: 100%; height: 3.333333rem; background: #fff; padding: 0.373333rem 0.32rem ...

  4. 【apio2007】【ctsc2007】 数据备份 贪心+链表+堆

    题目大意:有n个点,k条链,每个点离原点有一定的距离.要你用k条链连接2k个点,使得k条链的长度最短. 首先每次肯定是链相邻的2个点,所以我们先把相邻2个点的差值求出来,得到有n-1个数的数列. 然后 ...

  5. python-在定义函数时,不定长参数中,默认值参数不能放在必选参数前面

    如果一个函数的参数中含有默认参数,则这个默认参数后的所有参数都必须是默认参数,否则会报错:SyntaxError: non-default argument follows default argum ...

  6. 关于作用域范围Scope

    举个例子,如下: public class C { public int a = 2; public void test(int b) { int c = 3; for (int d = 3; a & ...

  7. 《Mysql技术内幕,Innodb存储引擎》——Innodb体系结构

    Innodb体系结构 Innodb存储引擎主要包括内存池以及后台线程. 内存池:多个内存块组成一个内存池,主要维护进程/线程的内部数据.缓存磁盘数据,修改文件前先修改内存.redo log 后台线程: ...

  8. 电信固定ip宽带80与8080端口踩坑

    本文只是作为记录,避免后面遇到此类问题耗费时间. 实际情况:公司有个固定电信宽带是固定IP的,想把固定IP映射到测试环境ip,实现可以公网通过固定ip访问,内网通过局域网ip访问. 测试环境服务是占用 ...

  9. springcloud-05-ribbon中不使用eureka

    ribbon在有eureka的情况下, 可以不使用eureka, 挺简单, 直接上代码 application.xml server: port: spring: # 设置eureka中注册的名称, ...

  10. equal&==&hashcode

    == 和 equals 的区别 Object类中的equals方法和“==”是一样的,没有区别,而String类,Integer类等等一些类,是重写了equals方法,才使得equals和“==不同” ...