BZOJ3239
BSGS
#include <cstdio> #include <cmath> #include <map> #define LL long long using namespace std; LL p,b,n; map <int,int> mp; LL qpow(LL bas,int powe,LL mo){ LL ret=1; for (;powe;bas*=bas,bas%=mo){ if (powe&1) ret*=bas,ret%=mo; powe=powe>>1; } return(ret); } int main(){ while (scanf("%lld%lld%lld",&p,&b,&n)!=EOF){ mp.clear(); int bl=(int)sqrt(p);LL tb,bas; bas=tb=qpow(b,bl,p); for (int i=1;i<=bl;i++){ if (mp[bas]==0) mp[bas]=i*bl; bas*=tb;bas%=p; } tb=1; LL ans=1e9; for (LL i=0;i<=bl;i++){ if (tb==n) ans=min(ans,i); LL t=qpow(tb,p-2,p)*n%p; if (mp[t]) ans=min(ans,mp[t]+i); tb*=b;tb%=p; } if (ans!=1e9) printf("%lld ",ans);else printf("no solution "); } }
a^x==b(mod p)\ 得 a^x+k*p==b\ 设 g=gcd(a,p),那么frac{b}{g}为整数\ 得frac{a}{g}a^{x-1}+kfrac{p}{g}=frac{b}{g}\ frac{a}{g}a^{x-1}==frac{b}{g}(mod frac{p}{g})\ a^{x-1}==frac{b}{g}(frac{a}{g})^{-1}(mod frac{p}{g})\ a^{x’}=={b’}(mod {m’})\ 其中 x’=x-1\ b’=frac{b}{g}(frac{a}{g})^{-1}\ m’=frac{p}{g} |
-----------------------------------------------------------
BZOJ2754
使用map记录AC自动机的出边
#include <cstdio> #include <map> using namespace std; int a[200001]; map <int,int> mp[200001]; int next[200001],scnt,nd[200001],des[200001],cha[200001],cnt; int ans1[200001],ans2[200001],quenext[200001],qnd[200001]; int dl[200001],fail[200001],vis[200001],worktim,len[200001]; int pool[200001],n,m; void addedge(int x,int y,int ch){ next[++scnt]=nd[x];des[scnt]=y;cha[scnt]=ch;nd[x]=scnt; } void insert(int id){ int len=0,t; scanf("%d",&t); for (int i=1;i<=t;i++) scanf("%d",&a[++len]); int po=1; for (int i=1;i<=len;i++){ if (!mp[po][a[i]]) addedge(po,cnt+1,a[i]),po=mp[po][a[i]]=++cnt;else po=mp[po][a[i]]; } quenext[id]=qnd[po];qnd[po]=id; } void getfail(){ int head,tail; head=1;tail=0; for (int p=nd[1];p;p=next[p]){ dl[++tail]=des[p];fail[des[p]]=1; } while (head<=tail){ for (int p=nd[dl[head]];p;p=next[p]){ int x=fail[dl[head]],y=cha[p]; while (x&&!mp[x][y]) x=fail[x]; if (!x) fail[des[p]]=1;else fail[des[p]]=mp[x][y]; dl[++tail]=des[p]; } head++; } } void getans(int po,int id){ for (;po;po=fail[po]){ if (vis[po]==worktim) return; vis[po]=worktim; for (int p=qnd[po];p;p=quenext[p]){ ans1[p]++;ans2[id]++; } } } void solve(int id){ int po=1;worktim++; for (int i=1;i<=len[id];i++){ int num=pool[++pool[0]]; while (po&&!mp[po][num]) po=fail[po]; if (po==0) po=1;else po=mp[po][num]; getans(po,id); } } int main(){ scanf("%d%d",&n,&m); cnt=1;pool[0]=0; for (int i=1;i<=n;i++){ int t; scanf("%d",&t);len[i]+=t; for (int j=1;j<=t;j++) scanf("%d",&pool[++pool[0]]); len[i]++;pool[++pool[0]]=1e9; scanf("%d",&t);len[i]+=t; for (int j=1;j<=t;j++) scanf("%d",&pool[++pool[0]]); }pool[0]=0; for (int i=1;i<=m;i++) insert(i); getfail(); for (int i=1;i<=n;i++) solve(i); for (int i=1;i<=m;i++) printf("%d ",ans1[i]); for (int i=1;i<n;i++) printf("%d ",ans2[i]); printf("%d",ans2[n]); }