我们定义第一个集合为a, 第二个集合为b
先把a数组排序, 然后我们会以线段的形式得到b集合。
我们先用a[ 1 ]去和 b 中的元素结合, 只有size(a) 个数字未被覆盖, 我们从这些数组中选答案。
枚举这些数字, 什么情况下才它是答案呢, 就是移到a[ 2 ], a[ 3 ], a[ 4 ], 它都是未被覆盖的数组,
这个东西可以用hash值维护一下就能O(1)check啦。
#include<bits/stdc++.h> #define LL long long #define LD long double #define ull unsigned long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ALL(x) (x).begin(), (x).end() using namespace std; const int N = 4e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-8; const double PI = acos(-1); template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;} template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;} template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;} template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;} int n, m, a[N]; vector<PII> seg; vector<int> vc; vector<int> ans; ull HashVal; ull hs[N], Pow[N]; ull getHash(int L, int R) { return hs[R] - hs[L - 1] * Pow[R - L + 1]; } int main() { for(int i = Pow[0] = 1; i < N; i++) Pow[i] = Pow[i - 1] * 23333; scanf("%d%d", &n, &m); if(n == 0 || n == m) return puts("0"), 0; for(int i = 1; i <= n; i++) scanf("%d", &a[i]); sort(a + 1, a + 1 + n); a[n + 1] = m; a[0] = -1; for(int i = 0; i <= n; i++) if(a[i] + 1 < a[i + 1]) seg.push_back(mk(a[i] + 1, a[i + 1] - 1)); seg.push_back(mk(-1, -1)); seg.push_back(mk(m, m)); sort(ALL(seg)); for(int i = 0; i < SZ(seg) - 1; i++) for(int j = seg[i].se + 1; j < seg[i + 1].fi; j++) vc.push_back((j + a[1]) % m), vc.push_back((j + a[1]) % m - m); sort(ALL(vc)); for(int i = n - 1; i >= 1; i--) HashVal *= 23333, HashVal += a[i + 1] - a[i]; n--; for(int i = 1; i < SZ(vc); i++) hs[i] = hs[i - 1] * 23333 + vc[i] - vc[i - 1]; for(int i = SZ(vc) / 2; i < SZ(vc); i++) if(getHash(i - n + 1, i) == HashVal) ans.push_back(vc[i]); printf("%d\n", SZ(ans)); for(auto& t : ans) printf("%d ", t); if(SZ(ans))puts(""); return 0; } /* */