zoukankan      html  css  js  c++  java
  • OpenJ_POJ 1058 Guideposts

    Problem

    OpenJ_POJ

    Solution

    如果我们用 \(G\) 来表示邻接矩阵,那么答案其实就是求\(\sum_{k|i}^n \binom n i G^i\)

    为了消除整除的限制,我们可以考虑单位根反演:

    \[\frac 1 k\sum_{i=0}^{k-1}w_k^{in}=[k|n] \]

    那么原题就是要求

    \[\frac 1 k\sum_{i=0}^n \binom n i G^i\sum_{j=0}^{k-1}w_k^{ij} \]

    \[\frac 1 k\sum_{j=0}^{k-1}\sum_{i=0}^n \binom n i (Gw_k^j)^i \]

    \[\frac 1 k\sum_{j=0}^{k-1}(Gw_k^j+1)^n \]

    注意到题目的一个限制\(P\equiv 1 \pmod k\),此时有\(w_k=g^{\frac {p-1} {k}}\)。为什么呢?因为\(w_k^k=1=g^{p-1}\),而且显然根据原根的性质,\(\forall_{i<k} w_k^i\)都两两不相等。

    时间复杂度\(O(km^3\log n)\)

    Code

    #include <cstring>
    #include <cstdio>
    using namespace std;
    typedef long long ll;
    template <typename Tp> inline int getmin(Tp &x,Tp y){return y<x?x=y,1:0;}
    template <typename Tp> inline int getmax(Tp &x,Tp y){return y>x?x=y,1:0;}
    template <typename Tp> inline void read(Tp &x)
    {
        x=0;int f=0;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=1,ch=getchar();
        while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        if(f) x=-x;
    }
    int m,k,l,s,t,cnt,mod,G,wk,ans,pri[40];
    ll n;
    int pls(int x,int y){return x+y>=mod?x+y-mod:x+y;}
    int dec(int x,int y){return x-y<0?x-y+mod:x-y;}
    struct Matrix{
    	int a[5][5];
    	Matrix(){memset(a,0,sizeof(a));}
    	int* operator [] (int x){return a[x];}
    	void clear(){memset(a,0,sizeof(a));}
    	Matrix operator * (Matrix &b)const
    	{
    		Matrix res;
    		for(int i=0;i<5;i++)
    		  for(int k=0;k<5;k++)
    		    for(int j=0;j<5;j++)
    		      res[i][j]=pls(res[i][j],(ll)a[i][k]*b[k][j]%mod);
    		return res;
    	}
    	Matrix operator + (Matrix b)const
    	{
    		Matrix res;
    		for(int i=0;i<5;i++)
    		  for(int j=0;j<5;j++)
    		    res[i][j]=pls(a[i][j],b[i][j]);
    		return res;
    	}
    	Matrix operator * (const int &b)const
    	{
    		Matrix res;
    		for(int i=0;i<5;i++)
    		  for(int j=0;j<5;j++)
    		    res[i][j]=(ll)a[i][j]*b%mod;
    		return res;
    	}
    }A,B,C,E;
    int power(int x,int y)
    {
    	int res=1;
    	for(;y;y>>=1,x=(ll)x*x%mod)
    	  if(y&1ll)
    	    res=(ll)res*x%mod;
    	return res;
    }
    Matrix mat_pow(Matrix x,ll y)
    {
    	Matrix res=x;
    	for(--y;y;y>>=1,x=x*x)
    	  if(y&1)
    	    res=res*x;
    	return res;
    }
    void find_G()
    {
    	int x=mod-1,f;
    	for(int i=2;i*i<=x;i++)
    	  if(x%i==0)
    	  {
    	  	pri[++cnt]=i;
    	  	while(x%i==0) x/=i;
    	  }
    	if(x>1) pri[++cnt]=x;
    	for(G=2;;G++)
    	{
    		f=1;
    		for(int j=1;j<=cnt;j++)
    		  if(power(G,(mod-1)/pri[j])==1)
    		    {f=0;break;}
    		if(f) return ;
    	}
    }
    int input()
    {
    	int u,v;
    	if(scanf("%d",&m)==EOF) return 0;
    	cnt=0;A.clear();B.clear();C.clear();
    	read(n);read(k);read(mod);
    	read(l);read(s);read(t);--s;--t;
    	for(int i=1;i<=l;i++)
    	{
    		read(u);read(v);
    		++C[v-1][u-1];
    	}
    	for(int i=0;i<5;i++) E[i][i]=1;
    	find_G();B[s][0]=1;
    	return 1;
    }
    int main()
    {
    	while(input())
    	{
    		wk=power(G,(mod-1)/k);
    		for(int i=0;i<k;i++,C=C*wk)
    		  A=A+mat_pow(C+E,n);
    		A=A*B;
    		ans=(ll)A[t][0]*power(k,mod-2)%mod;
    		printf("%d\n",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    【加密】 RSA
    【Resource】【ResourceLoader】【ResourcePatternResolver】学习
    【拦截器】Springboot项目之拦截器使用
    【OpenSSl】linux下OpenSSL的RSA密钥生成
    【微服务架构】图解
    【md5】几种常见的数据摘要算法(MD5、CRC32、SHA1和SHA256)
    【VM VirtualBox】【Vagrant】的安装及使用
    VUE中解决echarts数据二次渲染不成功的问题xAxis
    TypeError: Cannot read property 'map' of null
    VS code 卡顿很严重
  • 原文地址:https://www.cnblogs.com/totorato/p/10387933.html
Copyright © 2011-2022 走看看