原题链接

DOWNLOAD AS PDF

题目大意

\(0\sim m-1\)的数被分成两个集合,你可以分别从两个集合中取一个数相加并对\(m\)取模,求一不能构造出的数。

题解

感觉如果\(\color{black}\sf{s}\color{red}\sf{xd666}\)来做这题肯定能一眼秒,然而他正忙着切其他题。

首先我们发现如果要让\(a + b \equiv x \pmod m\),如果已知\(a, x\),那\(b\)一定是唯一的。也就是说,假设给定集合是\(A\),与之对应的集合为\(B\),如果有\(a\in A\)但找不到\(b\in A\)使得\(a + b \equiv x\pmod m\)。那么\(x\in A + B\)(定义\(A + B = \{a + b : a\in A, b\in B\}\))。反过来讲,如果\(x\notin A + B\),那么一定能把\(A\)中所有元素配对(可能两个数相同),也即\(x\notin A + B \iff A = x - A\)(定义\(x - A= \{x - a : a\in A\}\))。

然后我们如果把小于\(m\)的整数看成一个环,如果有两个数\(a, b\)使\(a + b \equiv x \pmod m\),\(a\)顺时针时针移动,\(b\)肯定逆时针移动(即运动方向相反,且移动的长度应该是相等的(\((a + k)\mod m + (b - k)\mod m \equiv a + b \pmod m\)嘛)。

于是我们画两个圆,都表示集合\(\{a_i\}\)(假设\(a_i\)已经排好序),我们要把第一个圆的点与第二个圆的点匹配。

假设\(a_i\)与\(a_j\)匹配。我们把\(i\)移动至\(i+1\),那么根据上面推出的单调性,\(j\)必须移至\(j-1\)(因为\(a_i\sim a_{i+1}\)之间没有数了,所以\(j\)也只能移动一格),又因为移动距离必须相等,即\(a_{i+1} - a_i = a_j - a_{j-1}\)。

所以我们令\(b_i = a_{i} - a_{i-1}\)(\(b_1 = (a_1 - a_n)\mod m\)),设串\(s_1 = b_nb_{n-1}b_{n-2}\cdots b_1, s_2 = b_1b_2b_3\cdots b_n\),我们要找的是\(s_1\)与\(s_2\)成环后相等,并找到一对匹配的数,他们加起来模\(m\)即为一组解。我们令\(s_3 = s_2 + s_2\),找到\(s_3\)中所有等于\(s_1\)的子串,就得到了所有解,这个问题用KMP或是Z都能解决。

还是贴一下代码吧:

#include <cstdio>
#include <set>
#include <vector>
#include <iostream>
#include <algorithm> using namespace std; typedef long long LL; const int maxn = 200005; LL aa[maxn]; // 读入的a
LL bb[maxn]; // 即上面说的b
vector<LL> gou;
int in[maxn << 2];
LL Z[maxn << 2];
set<LL> ans; int main()
{
int n;
LL m;
scanf("%d%lld", &n, &m);
for(int i = 1; i <= n; ++i)
scanf("%lld", &aa[i]);
bb[1] = ((aa[1] - aa[n]) + m) % m;
for(int i = 2; i <= n; ++i)
bb[i] = ((aa[i] - aa[i-1]) % m + m) % m;
for(int i = n; i; --i) // 这里用的是Z算法,所以合并成了一个串
{
gou.push_back(bb[i]);
in[gou.size() - 1] = i;
}
gou.push_back(-1LL);
for(int i = 1; i <= n; ++i)
{
gou.push_back(bb[i]);
in[gou.size() - 1] = i;
}
for(int i = 1; i <= n; ++i)
{
gou.push_back(bb[i]);
in[gou.size() - 1] = i;
}
Z[0] = gou.size();
for(int i = 1, j = 1, k; i < (int) gou.size(); i = k) // Z算法
{
j = max(j, i);
while(gou[j] == gou[j - i])
++j;
Z[i] = j - i;
k = i + 1;
while(k + Z[k - i] < j)
{
Z[k] = Z[k - i];
++k;
}
}
for(int i = 1; i < (int) gou.size(); ++i)
if(Z[i] >= n) // 大力记录答案
ans.insert((aa[in[i] - 1 ? in[i] - 1 : n] + aa[n]) % m);
printf("%d\n", (int) ans.size());
for(auto it = ans.begin(); it != ans.end(); ++it)
printf("%lld ", *it);
return 0;
}

CF1045B Space Isaac的更多相关文章

  1. CF1045B Space Isaac(乱搞)

    翻译 有0~m-1的数被分成了两个集合每次你可以从两个集合中任取一个数做加法并对m取模问最后0~m-1中不能被组合出来的数有多少个会给出你A集合 大小不超过200000m<=1e9 完了题解都看 ...

  2. Codeforces 1045B Space Isaac

    Space Isaac 我们定义第一个集合为a, 第二个集合为b 先把a数组排序, 然后我们会以线段的形式得到b集合. 我们先用a[ 1 ]去和 b 中的元素结合, 只有size(a) 个数字未被覆盖 ...

  3. codeforces1045B Space Isaac 【manacher】【差分】

    题目大意: 题目是将$[0,m)$的数划成了两个集合,其中一个集合的元素个数不超过$n$.问在第一个集合中选出的数加上第二个集合中选出的数的和中没有出现的数有哪些. 题目分析: 很有意思的一道题.方便 ...

  4. Codeforces 1045B Space Isaac - 数论 - Hash

    题目传送门 传送门I 传送门II 传送门III 题目大意 给定将$\left \{ 0, 1, \dots, m - 1\right \}$分成了不相交的两个非空集合$A$和$B$,给定$A$,问存在 ...

  5. Noip前的大抱佛脚----赛前任务

    赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...

  6. 【做题】CF1045(ABH)

    原文链接https://www.cnblogs.com/cly-none/p/9697662.html 题目当然不会做完了,这里只讲有做&会做的. A. Last chance 题意:有\(n ...

  7. codeforce1046 Bubble Cup 11 - Finals 题解

    比赛的时候开G开了3h结果rose说一句那唯一一个AC的是羊的心态就崩了.. 这套题感觉质量挺好然后就back了下 A: AI robots 有三个限制条件:相互能够看见和智商的差.使用主席树,可以维 ...

  8. Bubble Cup 11 - Finals [Online Mirror, Div. 1]题解 【待补】

    Bubble Cup 11 - Finals [Online Mirror, Div. 1] 一场很好玩的题啊! I. Palindrome Pairs 枚举哪种字符出现奇数次. G. AI robo ...

  9. java head space/ java.lang.OutOfMemoryError: Java heap space内存溢出

    上一篇JMX/JConsole调试本地还可以在centos6.5 服务器上进行监控有个问题端口只开放22那么设置的9998端口 你怎么都连不上怎么监控?(如果大神知道还望指点,个人见解) 线上项目出现 ...

随机推荐

  1. Moving x86 assembly to 64-bit (x86-64)

    While 64-bit x86 processors have now been on the market for more than 5 years, software support is o ...

  2. 10.python3实用编程技巧进阶(五)

    5.1.如何派生内置不可变类型并修其改实例化行为 修改实例化行为 # 5.1.如何派生内置不可变类型并修其改实例化行为 #继承内置tuple, 并实现__new__,在其中修改实例化行为 class ...

  3. 【洛谷4920】[WC2015] 未来程序(提答题)

    点此看题面 大致题意: 把\(10\)个点的暴力代码和输入数据都给你,让你求出输出数据. 子任务\(1\) 第一个子任务自然是拿来送分用的... 容易发现就是一个快速乘的过程啊. 代码如下: #inc ...

  4. matlab练习程序(DBSCAN)

    DBSCAN全称Density-Based Spatial Clustering of Applications with Noise,是一种密度聚类算法. 和Kmeans相比,不需要事先知道数据的类 ...

  5. Paper | Non-Local ConvLSTM for Video Compression Artifact Reduction

    目录 1. 方法 1.1 框图 1.2 NL流程 1.3 加速版NL 2. 实验 3. 总结 [这是MFQE 2.0的第一篇引用,也是博主学术生涯的第一篇引用.最重要的是,这篇文章确实抓住了MFQE方 ...

  6. Spring @CrossOrigin 通配符 解决跨域问题

    @CrossOrigin 通配符 解决跨域问题 痛点: 对很多api接口需要 开放H5 Ajax跨域请求支持 由于环境多套域名不同,而CrossOrigin 原生只支持* 或者具体域名的跨域支持 所以 ...

  7. RESTful Webservice 和 SOAP Webserivce 对比及区别【转】

    接口抽象 RESTful Web 服务使用标准的 HTTP 方法 (GET/PUT/POST/DELETE) 来抽象所有 Web 系统的服务能力,而不同的是,SOAP 应用都通过定义自己个性化的接口方 ...

  8. Python机器学习笔记 Grid SearchCV(网格搜索)

    在机器学习模型中,需要人工选择的参数称为超参数.比如随机森林中决策树的个数,人工神经网络模型中隐藏层层数和每层的节点个数,正则项中常数大小等等,他们都需要事先指定.超参数选择不恰当,就会出现欠拟合或者 ...

  9. Kubernetes Secret(机密存储)

    Kubernetes Secret(机密存储) 官方文档:https://kubernetes.io/docs/concepts/configuration/secret/ 加密数据并存放Etcd中, ...

  10. JVM的参数以及作用详解

    -XX:+PrintCommandLineFlags   打印出JVM运行时的各种的各项配置参数 -verbose:gc   发生GC时,打印出GC日志-XX:+printGC 发生GC时,打印出GC ...