[BZOJ 5330][SDOI2018] 反回文串

传送门

怎么说呢,一道不可多得的反演题吧,具体解释之后再补

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define rep(i,a,b) for(int i=a;i<=b;++i)
 4 typedef long long ll;
 5 const int maxn=500010;
 6 ll mul(ll x,ll y,ll p) {
 7     x%=p; y%=p;
 8     return (x*y-(ll)((long double)x/p*y+0.5)*p+p)%p;
 9 }
10 ll _pow(ll x,ll n,ll p) {
11     ll ret=1;
12     for(;n;n>>=1,x=mul(x,x,p)) if(n&1) ret=mul(ret,x,p);
13     return ret;
14 }
15 ll tp[6]={2LL,3LL,5LL,7LL,13LL,61LL};
16 bool MR(ll n) {
17     if(n==1) return false;
18     rep(i,0,5) if(n==tp[i]) return true;
19     rep(i,0,5) if(n%tp[i]==0) return false;
20     rep(i,0,5) {
21         ll tmp=n-1;while(!(tmp&1)) tmp>>=1;
22         ll s=_pow(tp[i],tmp,n);
23         while(s!=n-1&&s!=1&&tmp!=n-1) tmp<<=1,s=mul(s,s,n);
24         if(s!=n-1&&!(tmp&1)) return false;
25     }
26     return true;
27 }
28 ll PR(ll n,ll c) {
29     ll i=0,k=2LL,x,y; x=y=1LL+rand()%(n-1);
30     while(1) {
31         x=(mul(x,x,n)+c)%n;
32         ll d=__gcd((y-x+n)%n,n);
33         if(d!=1&&d!=n) return d;
34         if(x==y) return n;
35         if(++i==k) y=x,k<<=1;
36     }
37 }
38 int op[maxn],len,cnt,T;
39 ll n,P,K,ans,gt[maxn];
40 inline void fct(ll n) {
41     if(n==1) return; 
42     if(MR(n)){gt[++len]=n;return;}
43     ll p=n; 
44     for(int c=233;p==n;--c) p=PR(p,c);
45     fct(p); fct(n/p);
46 }
47 ll fpow(ll x,ll n,ll p) {
48     ll ret=1;
49     for(;n;n>>=1,x=x*x%p)
50         if(n&1) ret=ret*x%p;
51     return ret;
52 }
53 ll g(ll n) {return _pow(K,n+1LL>>1,P);}
54 ll f(ll n) {return n&1?n%P:(n>>1)%P;}
55 inline void dfs(int dp,ll d,ll pro) {
56     if(dp==cnt+1) {
57         if((n/d&1)&&(d&1)==0) return;
58         (ans+=1LL*g(n/d)*f(n/d)%P*pro%P)%=P;
59         return;
60     }
61     dfs(dp+1,d,pro); pro=1LL*pro*(1+P-gt[dp]%P)%P;
62     rep(i,1,op[dp]) d*=gt[dp],dfs(dp+1,d,pro);
63 }
64 int main() {
65 #ifndef ONLINE_JUDGE
66     freopen("25.in","r",stdin);
67 #endif
68     scanf("%d", &T);srand(19260817);
69     while(T--) {
70         scanf("%lld%lld%lld",&n,&K,&P);K%=P;
71         len=cnt=0;++cnt;
72         memset(gt,0,sizeof(gt)); memset(op,0,sizeof(op));
73         fct(n);
74         sort(gt+1,gt+1+len);
75         rep(i,1,len) {
76             if(gt[cnt]!=gt[i]) gt[++cnt]=gt[i],op[cnt]=0;
77             ++op[cnt];
78         }
79         ans=0;dfs(1,1LL,1LL);printf("%lld\n",ans);
80     }
81     return 0;
82 }
View Code

猜你喜欢

转载自www.cnblogs.com/miecoku/p/9756985.html