暑假集训csp提高模拟10

赛时 rank 19,T1 0,T2 25 T3 10 T4 100

T3 挂了10pts?

数学专场,套路专场,烧脑专场。

幸亏我还有缓存的李超树博客,最后一个小时就溜了去打数据结构。

数学好难,拜谢数学。

T1 黑暗型高松灯

Company Acquisitions

要用势能分析,鞅的停时定理。由于赛时这个放T1非常逆天,所以整场比赛的奖励也十分逆天。
image

不会做,跳了。

T2 速度型高松灯

[HNOI2011] 数学作业

按位考虑,矩阵快速幂。

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
#ifdef LOCAL
    FILE *InFile = infile("in.in"),*OutFile = outfile("out.out");
    // FILE *ErrFile=errfile("err.err");
#else
    FILE *Infile = stdin,*OutFile = stdout;
    //FILE *ErrFile = stderr;
#endif
#define int long long
int n,mod;
struct matrix{
	int s[3][3];
	matrix operator*(matrix a){
		matrix ans;
		memset(ans.s,0,sizeof ans.s);
		for(int i=0;i<3;i++)
		for(int j=0;j<3;j++)
		for(int k=0;k<3;k++)
		ans.s[i][j]=((ans.s[i][j]+a.s[i][k]*s[k][j])%mod+mod)%mod;
		return ans;
	}
}ans,base,k;
inline matrix new_one(){
	matrix a;
	memset(a.s,0,sizeof a.s);
	for(int i=0;i<3;i++)a.s[i][i]=1;
	return a;
}
inline matrix ksm(matrix a,int b){
	matrix ans = new_one();
	for(;b;b >>= 1,a = a*a)
	    if(b&1)ans = ans*a;
	return ans;
}
__int128_t ten[22];
signed main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    cout.tie(nullptr)->sync_with_stdio(false);
	cin>>n>>mod;
	n++;
	ten[0]=1;
	for(int i=1;i<=20;i++)ten[i]=ten[i-1]*10;
	memset(base.s,0,sizeof base.s);
	k.s[0][0]=0,k.s[1][0]=0,k.s[2][0]=1;
	base.s[0][2]=1,base.s[1][2]=1,base.s[2][1]=-1,base.s[2][2]=2;
	for(int i=1;i<=(int)ceil(1+log(n)/log(10.0));i++){
		base.s[0][0]=ten[i]%mod;
		if(n<ten[i]){
			k=k*ksm(base,n-ten[i-1]);
			return cout<<k.s[0][0],0;
		}k=k*ksm(base,ten[i]-ten[i-1]);
	}
}

T3 力量型高松灯

简单题

莫反,有个恶心的\((i+j)^k\)

\[\begin{aligned} &\sum_{i=1}^n\sum_{j=1}^n(i+j)^k\mu^2(\gcd(i,j))\gcd(i,j)\\ =&\sum_{d=1}^n\mu^2(d)d\sum_{i=1}^n\sum_{j=1}^n(i+j)^k[\gcd(i,j)=d]\\ =&\sum_{d=1}^n\mu^2(d)d^{k+1}\sum_{i=1}^{\lfloor\frac nd\rfloor}\sum_{j=1}^{\lfloor\frac nd\rfloor}(i+j)^k[\gcd(i,j)=1]\\ =&\sum_{d=1}^n\mu^2(d)d^{k+1}\sum_{i=1}^{\lfloor\frac nd\rfloor}\sum_{j=1}^{\lfloor\frac nd\rfloor}(i+j)^k\sum_{e|i,e|j}\mu(e)\\ =&\sum_{e=1}^n\mu(e)e^k\sum_{d=1}^{\lfloor\frac ne\rfloor}\mu^2(d)d^{k+1}\sum_{i=1}^{\lfloor\frac n{de}\rfloor}\sum_{j=1}^{\lfloor\frac n{de}\rfloor}(i+j)^k\\ =&\sum_{T=1}^nS\left(\left\lfloor\frac nT\right\rfloor\right)T^k\sum_{d|T}\mu^2(d)\mu\left(\frac Td\right)d \end{aligned} \]

其中 \(S(n)=\sum_{i=1}^n\sum_{j=1}^n(i+j)^k\)

考虑如何求\(S(n)\)

\(F(n) = \sum_{i=1}^ni^k,G(n)=\sum_{i=1}^nF(i)\),那么\(S(n)=G(2n)-2G(n)\)

线筛加前缀和就可以了

考虑后面的\(\sum_{d|T}\mu^2(d)\mu\left(\frac Td\right)d\)怎么求

我们设T有一个质因数p,若\(T=p^{3\,or\,more }\times sth.\),那么后面的就是0。

然后就没了

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
#ifdef LOCAL
    FILE *InFile = infile("in.in"),*OutFile = outfile("out.out");
    // FILE *ErrFile=errfile("err.err");
#else
    FILE *Infile = stdin,*OutFile = stdout;
    //FILE *ErrFile = stderr;
#endif
#define int long long
const int N = 1e7 + 10,mod = 998244353;
bitset<N> pd;
vector<int> prime;
int f[N],F[N],n,k;
inline int power(int a,int b,int mod){
    int res = 1;
    while(b){
        if(b&1) res = 1ll * res * a % mod;
        b >>= 1;
        a = 1ll * a * a % mod;
    }
    return res;
}
inline void Sieve(int n) {
	f[1] = F[1] = 1;
	for(int i = 2; i <= n; ++i) {
		if(!pd[i]) prime.push_back(i),f[i] = i - 1,F[i] = power(i,k,mod);
		for(auto j : prime) {
			if(i * j > n) break;
			int p = i * j;
			pd[p] = true;
			F[p] = 1ll * F[i] * F[j] % mod;
			if(i % j == 0) {
				int q = i / j;
				if(q % j) f[p] = 1ll * (mod - j) * f[q] % mod;
				break;
			} 
            f[p] = 1ll * f[i] * (j - 1) % mod;
		}
	}
	for(int i = 2; i <= n; ++i) f[i] = (f[i - 1] + 1ll * f[i] * F[i] % mod) % mod,F[i] = (F[i] + F[i - 1]) % mod;
	for(int i = 2; i <= n; ++i) F[i] = (F[i] + F[i - 1]) % mod;
}
inline int solve(int n){return (F[n<<1] - 2ll*F[n]%mod + mod)%mod;}
signed main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    cout.tie(nullptr)->sync_with_stdio(false);
    cin>>n>>k;k %= (mod-1);
    Sieve(n<<1);
    ll ans = 0;
    for(int l = 1,r;l <= n;l = r + 1){
        r = n / (n / l);
        ans = (ans + 1ll * (f[r]-f[l-1]+mod)%mod*solve(n/l)%mod)%mod;
    }
    cout<<ans;
}

T4 高松灯

贪心。

从低到高填9,计算答案即可。
特判第一位,如果后面的超限,那么就填第一位的数字-1,反之就填第一位的数字。

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
#ifdef LOCAL
    FILE *InFile = infile("in.in"),*OutFile = outfile("out.out");
    // FILE *ErrFile=errfile("err.err");
#else
    FILE *Infile = stdin,*OutFile = stdout;
    //FILE *ErrFile = stderr;
#endif
signed main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    cout.tie(nullptr)->sync_with_stdio(false);
    ll n;cin>>n;
    ll ans = 0;
    bool flag = true;
    while(n > 9){
        int x = n % 10;
        if(x != 9) flag = false;
        ans += 9;
        n /= 10;
    }
    ans += (flag?n:n-1);
    cout<<ans;
}

总结

逆天模拟赛

posted @ 2024-07-28 18:03  CuFeO4  阅读(21)  评论(0编辑  收藏  举报