写在前面:
今天是西元2017年8月17日,敬祝我们敬爱的长者,党和国家的前任领导同志生日快乐!
Problem 1. modlog
解题报告
#include <bits/stdc++.h>
using namespace std;
#define hash idyhash
const int S = 114281;
struct Hash {
int head[S], dest[S][2], last[S], etot;
void init() {
memset(head, 0, sizeof(head));
etot = 0;
}
void add(int a, int b) {
int key = a % S;
for(int t = head[key]; t; t = last[t])
if(dest[t][0] == a) return;
etot++;
last[etot] = head[key];
dest[etot][0] = a;
dest[etot][1] = b;
head[key] = etot;
}
int query(int a) {
int key = a % S;
for(int t = head[key]; t; t = last[t])
if(dest[t][0] == a) return dest[t][1];
return -1;
}
}hash;
int a, b, p;
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
int mpow(int a, int b, int mod) {
int rt;
for(rt = 1; b; b>>=1, a = (1LL*a*a)%mod)
if(b & 1) rt = (1LL*rt*a)%mod;
return rt;
}
void exgcd(int a, int b, int &d, int &x, int &y) {
if(b == 0) {
d = a;
x = 1;
y = 0;
} else {
int xx, yy;
exgcd(b, a%b, d, xx, yy);
// b * xx + (a - (a/b)*b) * yy = d
// a * yy + b * (xx - (a/b)*yy) = d
x = yy;
y = xx - a / b * yy;
}
}
int inverse(int a, int p) {
int d, x, y;
exgcd(a,p,d,x,y);
assert(d == 1);
// a * x + p * y = 1
return (x % p + p) % p;
}
int ind(int g, int a, int p) {
hash.init();
int b = (int)ceil(sqrt(a)) + 1;
int cur = 1;
for(int i = 0; i < b; i++, cur=(1LL*cur*g)%p) {
if(cur == a) return i;
hash.add(cur,i);
}
int base = inverse(cur,p);
cur = 1LL * base * a % p;
for(int i = b; i <= p - 1; i += b,cur=(1LL*cur*base)%p) {
int j = hash.query(cur);
if(j != -1) return i + j;
}
assert(false);
return -1;
}
vector<pair<int,int> > factor(int a) {
vector<pair<int,int> > fac;
for(int i = 2; i * i <= a; i++) {
if(a % i == 0) {
fac.push_back(make_pair(i,0));
while(a % i == 0) {
a /= i;
fac.back().second++;
}
}
}
if(a != 1) {
fac.push_back(make_pair(a,1));
}
return fac;
}
int findroot(int p) {
vector<pair<int,int> > fac = factor(p - 1);
for(int g = 1; ; g++) {
bool ok = true;
for(int t = 0; t < (int)fac.size(); t++) {
int q = fac[t].first;
if(mpow(g,(p - 1) / q,p) == 1) {
ok = false;
break;
}
}
if(ok) return g;
}
assert(false);
return -1;
}
int main() {
freopen("modlog.in", "r", stdin);
freopen("modlog.out", "w", stdout );
int T, type;
scanf("%d%d", &T, &type);
while(T--) {
scanf("%d%d%d", &a, &b, &p);
int cnt, sum;
if(b == 0) {
cnt = 1;
sum = 0;
} else {
int g = findroot(p);
int indb = ind(g,b,p);
int ph = p - 1;
int d = gcd(a,ph);
if(indb % d != 0) {
cnt = sum = 0;
} else {
// aa x = bb(cc)
int aa = a;
int bb = indb;
int cc = ph;
aa /= d, bb /= d, cc /= d;
bb = 1LL * bb * inverse(aa,cc) % cc;
cnt = ph / cc;
int q = mpow(g,cc,p);
if(q == 1) {
sum = 1LL * d * mpow(g,bb,p) % p;
} else {
sum = 0;
}
// g^bb,g^(bb+cc),...,g^(bb+ph-cc)
// g^bb(1 - g^(cc * ph/cc)) / (1 - g^cc)
}
}
if(type == 0)
printf("%d\n", cnt);
else
printf("%d %d\n", cnt, sum);
}
}
Problem 2. sumit
解题报告
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define NAME "sumit"
using namespace std;
const int N=1e7;
const int mod=10086;
int n,m,t;
long long p[N+5],phi[N+5],prime[N+5];
long long ans;
void get_phi()
{
phi[1]=1;
for(int i=2;i<=N;++i)
{
if(!p[i])
{
prime[++prime[0]]=i;
phi[i]=i-1;
}
for(int j=1;j<=prime[0]&&i*prime[j]<=N;++j)
{
p[i*prime[j]]=1;
if(i%prime[j]==0)
{
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
else phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
phi[i]+=phi[i-1];
}
}
int main()
{
freopen(NAME".in","r",stdin);
freopen(NAME".out","w",stdout);
get_phi();
for(scanf("%d",&t);t;--t)
{
ans=0;
scanf("%d%d",&n,&m);
if(n>m) swap(n,m);
for(int i=1,j;i<=n;i=j+1)
{
j=min(n/(n/i),m/(m/i));
ans+=(((phi[j]-phi[i-1])%mod)*((long long)n/i)%mod)*((long long)m/i)%mod;
}
printf("%I64d\n",ans%mod);
}
return 0;
}
Problem 3. secret
解题报告
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define NAME "secret"
using namespace std;
const int INF=0x3f3f3f3f,N=1e7;
int n,mu[N+5],prime[N+5],num=0;
ll a[N+5],c,d,m;
void M()
{
memset(mu,INF,sizeof(mu));
mu[1]=1;
for(ll i=2;i<N+5;++i)
{
if(mu[i]==INF)prime[++num]=i,mu[i]=-1;
for(ll j=1;j<=num&&i*prime[j]<N+5;++j)
{
if(i%prime[j]==0){mu[i*prime[j]]=0;break;}
else mu[i*prime[j]]=-mu[i];
}
}
}
int main()
{
freopen(NAME".in","r",stdin);
freopen(NAME".out","w",stdout);
M();
scanf("%d %I64d %I64d %I64d %I64d",&n,&a[1],&c,&d,&m);
ll b1=a[1]*mu[1];
for(ll i=2;i<=n;++i)a[i]=(c*a[i-1]+d)%m,b1+=a[i]*mu[i];
printf("%I64d\n",b1);
return 0;
}