答题情况
总成绩 : 169 , 排名 : NaN
T1 : 9 T2 : 100 T3 : 60
各题目分析
题目 1 :
预估成绩 : 20 实际成绩 : 9 考试用时 : 2:30 ~ 3:00, 4:00 ~ 5:00
一开始死磕T1, 推出了比较优美但是没什么用的式子。
先打了暴力 之后看了其他题。
题目 2 :
预估成绩 : 100 实际成绩 : 100 考试用时 : 3:00 ~ 3:20
费马小定理应用的模板题。
之前有接触过,很快完成。
题目 3 :
预估成绩 : 100 实际成绩 : 60 考试用时 : 3:30 ~ 3:50
与之前做过的一道整除分块类似。
在此基础上添加了一些计算过程。
由于计算爆longlong丢了40分。
- 教训:注意数据范围!若数据范围较大 记得时刻取模。
题目解析
T1 :
18分:
暴力枚举s,暴力判断。
100分:
通过玄学打表可推出公式。
T2 :
费马小定理 简单应用。
指数较大,无法直接进行快速幂运算。
由于模数为质数,由费马小定理,有: \(a^{p-1} \equiv 1 \pmod p\)
则\(a^{b^c} \equiv a^{b^c \% (p - 1)} \pmod p\)
对指数和底数进行快速幂取余即可。
复杂度\(O(\log k)\)
T3 :
整除分块简单应用。
对于任一\(d\),\(1\sim n\)中其作为因数出现次数为 \(\dfrac{n}{d}\)。
可发现 \(\dfrac{n}{d}\) 在 \(d\) 递增时 递减。
则此因数对答案的贡献为 \(\lfloor \dfrac{n}{d}\rfloor \times d^2\)。
对于\(1\sim n\)的平方和,有公式为:\(\dfrac{n(n+1)(2n+1)}{6}\)。
记\(f(i) = \dfrac{i(i+1)(i+1)}{6}\)
由于\(\lfloor\dfrac{n}{d}\rfloor\)单调递减,存在众多值连续的区间。
对于出现次数均为\(\dfrac{n}{i}\) 的因数\(i\sim j\),
其总贡献为: \((f(j) - f(i-1)) \times \lfloor\dfrac{n}{i}\rfloor\)
显然上式可以通过 整除分块求解。
对于每一块\(\lfloor\dfrac{n}{i}\rfloor\)的区间,其贡献即为 \((f(j) - f(i-1)) \times \lfloor\dfrac{n}{i}\rfloor\)
注意随时取模
代码实现
T1 :
考场代码
//
/*
By:Luckyblock
*/
#include <cstdio>
#include <cctype>
#include <cstdlib>
#include <algorithm>
#define ll long long
const int MARX = 110 + 10;
const int mod = 1e9 + 7;
//=============================================================
int N, K, Ans, f[MARX] = {1};
//=============================================================
inline int read()
{
int f = 1, w = 0; char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for(; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0');
return f * w;
}
//=============================================================
int main()
{
freopen("cute.in", "r", stdin);
freopen("cute.out", "w", stdout);
N = read(), K = read();
for(int i = 1; i <= N; i ++) f[i] = f[i - 1] * K;
for(int s = 1; s < f[N]; s ++)
{
int flag = 1;
for(int i = 1; i < N - 1; i ++)
if(s % f[i] * f[N - i] <= s)
{flag = 0; break;}
Ans += flag, Ans %= mod;
}
printf("%d", Ans);
return 0;
}
正解
#include <iostream>
#include <algorithm>
using namespace std;
long long const P=1000000007,M=100000;
int m;
long long n,k,g[M],f[M];
bool isprime(long long x)
{
if (x==1) return false;
for (long long i=2;i*i<=x;i++)
if (x % i==0) return false;
return true;
}
long long comp(long long b,long long c,long long m)
{
long long ans=1;
long long l=b;
long long j=1;
while (j<=c)
{
if ((j & c)>0) ans=(ans*l) % m;
j*=2;
l=(l*l) % m;
}
return ans;
}
int main()
{
freopen("cute.in","r",stdin);
freopen("cute.out","w",stdout);
cin>>n>>k;
for (long long i=1;i*i<=n;i++)
if (n % i==0)
{
g[++m]=i;
if (i*i<n) g[++m]=n/i;
}
sort(g+1,g+m+1);
f[1]=k;
for (int i=2;i<=m;i++)
{
f[i]=comp(k,g[i],P);
for (int j=1;j<=i-1;j++)
if (g[i] % g[j]==0) f[i]=(f[i]+P-f[j]) % P;
}
printf("%lld\n",f[m]*comp(n,P-2,P) % P);
}
T2:
考场代码(正解)
//
/*
By:Luckyblock
*/
#include <cstdio>
#include <cctype>
#include <cstdlib>
#include <algorithm>
#define ll long long
//=============================================================
ll a, b, c, p;
//=============================================================
inline ll read()
{
ll f = 1, w = 0; char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for(; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0');
return f * w;
}
ll qpow(ll x, ll y, ll mod)
{
ll ret = 1;
for(; y; x = x * x % mod, y >>= 1)
if(y & 1) ret = ret *x % mod;
return ret;
}
//=============================================================
int main()
{
freopen("number.in", "r", stdin);
freopen("number.out", "w", stdout);
a = read(), b = read(), c = read(), p = read();
ll x = qpow(b, c, p - 1);
printf("%lld", qpow(a, x, p));
return 0;
}
T3:
考场代码(正解)
//
/*
By:Luckyblock
*/
#include <cstdio>
#include <cctype>
#include <cstdlib>
#include <algorithm>
#define ll long long
//=============================================================
ll N, Mod, ans, inv;
//=============================================================
inline ll read()
{
ll f = 1, w = 0; char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for(; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0');
return f * w;
}
ll qpow(ll x, ll y, ll mod)
{
ll ret = 1;
for(; y; x = x * x % mod, y >>= 1)
if(y & 1) ret = ret * x % mod;
return ret;
}
ll SquareSum(ll L, ll R)
{
ll suml = L * (L + 1) % Mod * (2 * L % Mod + 1) % Mod * inv % Mod;
ll sumr = R * (R + 1) % Mod * (2 * R % Mod + 1) % Mod * inv % Mod;
return (sumr - suml + Mod) % Mod;
}
//=============================================================
int main()
{
N = read(), Mod = read();
inv = qpow(6, Mod - 2, Mod);
for(ll i = 1, j; i <= N; i = j + 1)
{
j = N / (N / i);
ans = (ans + SquareSum((i - 1) % Mod , j % Mod) * (N / i) % Mod) % Mod;
}
printf("%lld\n", ans);
system("pause");
return 0;
}