You are given an integer m, and a list of n distinct integers between 0 and m - 1.
You would like to construct a sequence satisfying the properties:
- Each element is an integer between 0 and m - 1, inclusive.
- All prefix products of the sequence modulo m are distinct.
- No prefix product modulo m appears as an element of the input list.
- The length of the sequence is maximized.
Construct any sequence satisfying the properties above.
The first line of input contains two integers n and m (0 ≤ n < m ≤ 200 000) — the number of forbidden prefix products and the modulus.
If n is non-zero, the next line of input contains n distinct integers between 0 and m - 1, the forbidden prefix products. If n is zero, this line doesn't exist.
On the first line, print the number k, denoting the length of your sequence.
On the second line, print k space separated integers, denoting your sequence.
0 5
5 1 2 4 3 0
3 10 2 9 1
6 3 9 2 9 8 0
For the first case, the prefix products of this sequence modulo m are [1, 2, 3, 4, 0].
For the second case, the prefix products of this sequence modulo m are [3, 7, 4, 6, 8, 0].
当存在0<=a,b,x<m满足a∗x=b (mod m)
a∗x+m∗y=b => b%gcd(a,m)=0=>gcd(b,m)%gcd(a,m)=0
所以:①对任意a能到达b且b>0,gcd(b,m)>=gcd(a,m)
②当gcd(a,m)=gcd(b,m),a和b可以相互到达
于是把gcd(i,m)相同的数字缩为一个点
如果b>a且gcd(b,m)%gcd(a,m)==0,则在gcd(a,m)连一条边到gcd(b,m)
边的长度为∑m−1i=1(gcd(i,m)==gcd(b,m))
于是这个DAG图的最长路就是排除掉0的答案
而显然0如果可以用,必定是放在最后面的,最后判断0不是禁止使用就在答案加0即可
#include<stdio.h>
#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define MEM(a,x) memset(a,x,sizeof(a))
#define lowbit(x) ((x)&-(x))
using namespace std;
const int inf=0x3f3f3f3f;
const int N = 200000 + 5;
bool noUse[N];
int sccSize[N];
int pre[N],dis[N];
vector<int>vec;
vector<int>scc[N];
ll extend_gcd(ll a,ll b,ll&x,ll&y){
if(b==0){
x=1;
y=0;
return a;
}
int r=extend_gcd(b,a%b,y,x);
y-=x*(a/b);
return r;
}
void printAns(int i,int m){
deque<int>de;
vec.clear();
while(i!=-1){
for(auto x:scc[i]){
de.push_front(x);
}
i=pre[i];
}
if(!de.empty()){
vec.push_back(de[0]);
}
for(int i=1;i<de.size();++i){
int a=de[i-1],b=de[i];
ll x,y;
int d=extend_gcd(a,m,x,y);
x=((b/d*x)%m+m)%m;
vec.push_back(x);
}
if(!noUse[0]){
vec.push_back(0);
}
sort(de.begin(),de.end());
//cout<<"check:"<<(unique(de.begin(),de.end())==de.end())<<endl;
//cout<<"size:"<<vec.size()<<endl;
for(int i=0;i<vec.size();++i){
printf("%d%c",vec[i],i+1==vec.size()?'\n':' ');
}
}
void slove(int m){
MEM(sccSize,0);
vec.clear();
for(int i=1;i<m;++i){
scc[i].clear();
if(!noUse[i]){
int d=__gcd(i,m);
++sccSize[d];
scc[d].push_back(i);
}
}
for(int i=1;i<m;++i){
if(sccSize[i]){
dis[i]=sccSize[i];
vec.push_back(i);
}
}
//cout<<vec.size()<<endl;
MEM(pre,-1);
int ansIdx=-1,ans=0;
for(int i=0;i<vec.size();++i){
int a=vec[i];
for(int j=0;j<i;++j){
int b=vec[j];
if(a%b==0){
if(dis[a]<dis[b]+sccSize[a]){
pre[a]=b;
dis[a]=dis[b]+sccSize[a];
}
}
}
if(dis[a]>ans){
ans=dis[a];
ansIdx=a;
}
}
printf("%d\n",ans+(noUse[0]==0));
printAns(ansIdx,m);
}
int main()
{
//freopen("/home/lu/code/r.txt","r",stdin);
int n,m;
while(~scanf("%d%d",&n,&m)){
MEM(noUse,0);
for(int i=0;i<n;++i){
int x;
scanf("%d",&x);
noUse[x]=1;
}
slove(m);
}
return 0;
}