题意:Q次询问,每次给出a,n. n为素数,a和n互质,gcd(a,n)=1.
在[1,n-1]得范围内,找到所有满足x*x = a (mod n)的x.
Q<=1e5, a,n<=32767
每次O(N)枚举x,O(QN) TLE.
预处理:枚举n,在枚举x,[1,n-1]来更新答案mp[n][(x^x)%n]++ O(n^2 log n) TLE.
注意题目的条件 询问中的n都为素数并且n<=32676,询问中不同的n最多3512个 m=3512.
在[1,n-1]得范围内,找到所有满足x*x = a (mod n)的x.
Q<=1e5, a,n<=32767
每次O(N)枚举x,O(QN) TLE.
预处理:枚举n,在枚举x,[1,n-1]来更新答案mp[n][(x^x)%n]++ O(n^2 log n) TLE.
注意题目的条件 询问中的n都为素数并且n<=32676,询问中不同的n最多3512个 m=3512.
相同的n只进行一次暴力枚举. O(m*n+Q*logQ).
正解好像是二次剩余什么的..窝不会..
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=32768,M=3520,T=1e5+5;
const ll mod=1000000007ll;
int n,m,pn=0,pri[N],vis[N];
struct node{
int n,a,id;
}b[T];
bool cmp(node a,node b)
{
if(a.n==b.n)
return a.a<b.a;
return a.n<b.n;
}
void init()
{
for(int i=2;i<N;i++)
{
if(vis[i]) continue;
pri[++pn]=i;
for(int j=i+i;j<N;j+=i)
vis[j]=1;
}
}
vector<int> res[T];
void solve(int l,int r)
{
int f[N],n=b[l].n;
memset(f,-1,sizeof(f));
for(int i=l;i<=r;i++)
f[b[i].a]=b[i].id;//f[r]属于那次询问?
for(int i=1;i<n;i++)
{
int r=(i*i)%n;
if(f[r]!=-1)
res[f[r]].push_back(i);
}
// 2 : (2,7) (2,7)
for(int i=r;i>l;i--)
if(b[i].a==b[i-1].a)
res[b[i-1].id]=res[b[i].id];
}
int main()
{
init();
//cout<<pn<<endl;
int Q;
scanf("%d",&Q);
for(int i=1;i<=Q;i++)
scanf("%d%d",&b[i].a,&b[i].n),b[i].a%=b[i].n,b[i].id=i;
sort(b+1,b+1+Q,cmp);
for(int i=1,j=1;i<=Q;i=j)
{
while(j<Q&&b[i].n==b[j+1].n)
j++;
solve(i,j);
j++;
}
for(int i=1;i<=Q;i++)
{
if(res[i].size()==0)
printf("No root\n");
for(int j=0;j<res[i].size();j++)
printf("%d%c",res[i][j],j==res[i].size()-1?'\n':' ');
}
return 0;
}