Description
Tim拥有控制时间的能力。他学会了BFS后,出了一道题:求出一张无向图中连通块的个数。他想请你做出这道题来
Input
Output
T行,每行一个数,表示联通块的个数。
Sample Input
Sample Input1
1
998244353 4
1 3
Sample Input2
5
998244353 9088
709393585 591328017
998244353 8408
476368048 122172238
998244353 217
922587543 10
998244353 2948991
40846641 7
998244353 2692315
542601916 5
Sample Output
Sample Output2
998244349
样例解释
边为{1,3},{9,27},{81,243},{729,2187} ,所以共有998244349个联通块。
Sample Output2
998235265
998235945
998244136
995295362
995552038
Data Constraint
对所有数据,n=998244353, 1<=m,k,x<998244353, 1<=T<=10000
思路
考虑循环节,如果是加法,应该能想到找到循环节处理。考虑原根,相当于 ,就转变成了
加法,bsgs求出b就可以知道循环节。
循环节是偶数就是隔一个连一条边,是奇数就是一直合并直到成环
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
int t,p,m,x,k,cnt,a[1000077];
int power(int x,int y)
{
int ans=1;
while (y)
{
if (y&1) ans=(ll)ans*x%p;
x=(ll)x*x%p;
y>>=1;
}
return ans;
}
int main()
{
freopen("braid.in","r",stdin);
freopen("braid.out","w",stdout);
scanf("%d",&t);
for (int i=0;i<=23;i++)
{
a[++cnt]=1<<i;
a[++cnt]=7<<i;
a[++cnt]=17<<i;
a[++cnt]=119<<i;
}
sort(a+1,a+cnt+1);
while(t--)
{
scanf("%d%d%d%d",&p,&m,&x,&k);
if(x==0||k==0||k==1)
{
printf("%d\n",p); continue;
}
int i;
for(i=1; i<=cnt; i++) if(power(k,a[i])==1) break;
if(a[i]&1) a[i]=(a[i]<<1)-1;
if(m>a[i]>>1) m=a[i]>>1;
printf("%d\n",p-m);
}
}