reverse后差分循环同构:CF1045B

本文搬运自本人高中时期CSDN博客,若图片加载不出来,可到原文查看:https://blog.csdn.net/zhangtingxiqwq/article/details/135333770

https://www.luogu.com.cn/problem/CF1045B

分析题目可得,一个 xx 不能被凑出的充要条件是:

aA\forall a \in AaA\exist\, a'\in A ,满足: a+ab(modM)a+a'\equiv b\pmod M

显然 aa 变大时, aa' 会变小。对 aa 排序,然后reverse为 aa' 。如果 aaaa' 差分数组循环同构,则我们找出来一个 xx

1
2
3
4
5
pre coding at 
st coding at 9:29
st bugging at 9:41
passing at 9:48
fn blogging at 9:57
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include<bits/stdc++.h>
using namespace std;
#ifdef LOCAL
#define debug(...) fprintf(stdout, ##__VA_ARGS__)
#else
#define debug(...) void(0)
#endif
#define int long long
inline int read(){int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;
ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
#define Z(x) (x)*(x)
#define pb push_back
#define fi first
#define se second
//#define M
#define mo 998244353
#define g (int)(1e9+7)
#define N 400010
int n, m, i, j, k, T;
map<int, int>mp;
int s1[N], s2[N], c[N], a[N], b[N], M;
int d1[N], d2[N];
vector<int>ans;

void make(int *d, int n, int *s) {
int i;
for(i = 1; i<n; ++i) s[i] = (s[i-1] * g + d[i] ) % mo;
}

int qu(int l, int r, int *s) {
return ( (s[r] - (s[l - 1] * c[r - l + 1])) % mo + mo ) %mo;
}

signed main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
// srand(time(NULL));
// T=read();
// while(T--) {
//
// }
n=read(); M=read();
for(i=1; i<=n; ++i) a[i]=read();
sort(a+1, a+n+1);
for(i=1; i<=n; ++i) b[i]=-a[n-i+1];
for(i=1; i<=n; ++i) b[i+n]=b[i]+M;
for(i=1; i<=2*n; ++i) debug("%d ", b[i]); debug("\n");
for(i=c[0]=1; i<=2*n; ++i) c[i]=c[i-1]*g%mo;
for(i=1; i<n; ++i) d1[i]=a[i+1]-a[i]; make(d1, n, s1);
for(i=1; i<2*n; ++i) d2[i]=b[i+1]-b[i]; make(d2, 2*n, s2);
for(i=1; i<n; ++i) debug("%d ", s1[i]); debug("\n");
for(i=1; i<2*n; ++i) debug("%d ", s2[i]); debug("\n");
for(i=1; i<=n+1; ++i)
if(qu(1, n-1, s1) == qu(i, i + n - 2, s2)) {
k = ((a[1] - b[i]) % M + M) % M;
debug("%lld : %lld\n", i, k);
if(!mp[k]) ans.pb(k), mp[k]=1;
}
printf("%d\n", ans.size());
sort(ans.begin(), ans.end());
for(auto t : ans) printf("%lld ", t);
return 0;
}