暑假集训CSP提高模拟10
暑假集训CSP提高模拟10
组题人: @worldvanquisher
\(T1\) P170. 黑暗型高松灯 \(0pts\)
- 原题: CF1025G Company Acquisitions
- 科技题目,直接贺官方题解了。
考虑势能函数。如果我们使得每操作一步期望势能 \(-1\),那么初势能减末势能就是答案。
设一个点有 \(x\) 个儿子的势能为 \(f(x)\),那么考虑现在选中两个儿子个数为 \(x,y\) 的:
\[\frac 12(f(x+1)+yf(0))+\frac 12(f(y+1)+xf(0))-f(x)-f(y)=-1 \]不妨令 \(f(0)=0\) (其实好像是随意定的),那么同构一下得到 \(f(x)=1-2^x\),初减末即可。
其实是有应用条件的,但是大多数时候是你觉得能用就能用。详见 https://www.cnblogs.com/C202044zxy/p/16340757.html 第一道例题
部分分尊重原题。
\(T2\) P168. 速度型高松灯 \(95pts\)
-
设 \(F_{n}=\begin{bmatrix} n & f_{n} & 1 \end{bmatrix}\) ,容易有 \(\begin{aligned} F_{n} &= F_{10^{k-1}-1} \times \begin{bmatrix} 1 & 1 & 0 \\ 0 & 10^{k} & 0 \\ 1 & 1 & 1 \end{bmatrix}^{n-(10^{k-1}-1)} \end{aligned}\) ,其中 \(n \in [10^{k-1},10^{k})\) 。
-
因为 \(k \in [0, \left\lfloor \log_{10}n \right\rfloor+2]\) ,每个 \(k\) 单独算就行了。
点击查看代码
#define ll __int128_t struct Matrix { ll ma[5][5]; Matrix() { memset(ma,0,sizeof(ma)); } }f,a; Matrix mul(Matrix a,Matrix b,ll n,ll m,ll k,ll p) { Matrix c; for(ll i=1;i<=n;i++) { for(ll j=1;j<=k;j++) { for(ll h=1;h<=m;h++) { c.ma[i][j]=(c.ma[i][j]+a.ma[i][h]*b.ma[h][j]%p)%p; } } } return c; } Matrix qpow(Matrix a,ll b,ll p,ll n) { Matrix ans; for(ll i=1;i<=n;i++) { ans.ma[i][i]=1; } while(b) { if(b&1) { ans=mul(ans,a,n,n,n,p); } b>>=1; a=mul(a,a,n,n,n,p); } return ans; } int main() { ll b,p,n=1,m=3,k=3,i; scanf("%lld%lld",&b,&p); f.ma[1][3]=1; for(i=10;i/10<=b;i*=10) { a.ma[1][1]=a.ma[1][2]=a.ma[3][1]=a.ma[3][2]=a.ma[3][3]=1; a.ma[2][2]=i%p; f=mul(f,qpow(a,min(i,b+1)-i/10,p,m),n,m,k,p); } printf("%lld\n",f.ma[1][2]); return 0; }
\(T3\) P169. 力量型高松灯 \(0pts\)
-
部分分
- \(20pts\) :暴力枚举即可,时间复杂度为 \(O(n^{2} \log n+n \log k)\) ,可以使用扩展欧拉定理优化,使时间复杂度为 \(O(n^{2} \log^{2}n +n \log \sqrt{p})\) 。
-
正解
- 因涉及变量重名问题,以下所写的 \(m\) 指本题的 \(k\) 。
- 推式子,有 \(\begin{aligned} &\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}(i+j)^{m}\mu^{2}(\gcd(i,j))\gcd(i,j) \\ &=\sum\limits_{k=1}^{n}\mu^{2}(k)k\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}(i+j)^{m} [\gcd(i,j)=k] \\ &=\sum\limits_{k=1}^{n}\mu^{2}(k)k\sum\limits_{i=1}^{\left\lfloor \frac{n}{k} \right\rfloor}\sum\limits_{j=1}^{\left\lfloor \frac{n}{k} \right\rfloor}(ik+jk)^{m} [\gcd(i,j)=1] \\ &=\sum\limits_{k=1}^{n}\mu^{2}(k)k^{m+1}\sum\limits_{i=1}^{\left\lfloor \frac{n}{k} \right\rfloor}\sum\limits_{j=1}^{\left\lfloor \frac{n}{k} \right\rfloor}(i+j)^{m}\sum\limits_{d|\gcd(i,j)}\mu(d) \\ &=\sum\limits_{k=1}^{n}\mu^{2}(k)k^{m+1}\sum\limits_{d=1}^{\left\lfloor \frac{n}{k} \right\rfloor}\mu(d)\sum\limits_{i=1}^{\left\lfloor \frac{n}{kd} \right\rfloor}\sum\limits_{j=1}^{\left\lfloor \frac{n}{kd} \right\rfloor}(id+jd)^{m} \\ &=\sum\limits_{k=1}^{n}\mu^{2}(k)k^{m+1}\sum\limits_{d=1}^{\left\lfloor \frac{n}{k} \right\rfloor}\mu(d)d^{m}\sum\limits_{i=1}^{\left\lfloor \frac{n}{kd} \right\rfloor}\sum\limits_{j=1}^{\left\lfloor \frac{n}{kd} \right\rfloor}(i+j)^{m} \\ &=\sum\limits_{T=1}^{n}T^{m}\sum\limits_{k|T}\mu^{2}(k)\mu(\frac{T}{k})k\sum\limits_{i=1}^{\left\lfloor \frac{n}{T} \right\rfloor}\sum\limits_{j=1}^{\left\lfloor \frac{n}{T} \right\rfloor} (i+j)^{m} \end{aligned}\) 。
- 设 \(\begin{cases} s(n)=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}(i+j)^{m} \\ h(i)=i^{m} \\ f(n)=\sum\limits_{i=1}^{n}h(i) \\ g(n)=\sum\limits_{i=1}^{n}f(i) \end{cases}\) ,数形结合有 \(\begin{aligned} &s(n) \\ &=s(n-1)+f(2n)+f(2n-1)-2f(n) \\ &=g(2n)-2g(n) \end{aligned}\) 。每个数单独计算其 \(h\) 值时间复杂度不可接受,我们发现 \(h\) 为完全积性函数,可以线筛预处理,也可以使用扩展欧拉定理优化。
- 原式可以写作 \(\begin{aligned} &=\sum\limits_{T=1}^{n}s(\left\lfloor \frac{n}{T} \right\rfloor)T^{m}\sum\limits_{k|T}\mu^{2}(k)\mu(\frac{T}{k})k \end{aligned}\) ,
- 设 \(w(n)=n^{m}\sum\limits_{d|n}\mu^{2}(d)\mu(\frac{n}{d})d\) ,显然 \(w\) 为积性函数。现在把关注点放在后面的 \(\mu^{2}(k)\mu(\frac{T}{k})\) 上,二者必须同时为 \(1\) 才对答案产生贡献,即 \(k,\frac{T}{k}\) 均没有平方质因子,那么 \(T\) 就不能有一个质因子的次数 \(\ge 3\) ,线筛时记录下次数即可。
- \(\begin{cases} w(p)=p^{m}(p-1) \\ w(p^{2})=p^{2m} \times (-p) \end{cases}\)
- 维护 \(w\) 的前缀和,整除分块维护 \(\frac{n}{T}\) 即可。
- 略卡空间,无用空间回收利用。
点击查看代码
const ll p=998244353,phi=998244352; ll prime[10000010],h[10000010],w[10000010],len=0; bool vis[10000010]; ll qpow(ll a,ll b,ll p) { ll ans=1; while(b) { if(b&1) { ans=ans*a%p; } b>>=1; a=a*a%p; } return ans; } void isprime(ll n,ll k) { memset(vis,0,sizeof(vis)); h[1]=w[1]=1; for(ll i=2;i<=2*n;i++) { if(vis[i]==0) { len++; prime[len]=i; h[i]=qpow(i,k,p); w[i]=i-1; } for(ll j=1;j<=len&&i*prime[j]<=2*n;j++) { vis[i*prime[j]]=1; h[i*prime[j]]=h[i]*h[prime[j]]%p; if(i%prime[j]==0) { w[i*prime[j]]=((i/prime[j])%prime[j]!=0)*w[i/prime[j]]*(-prime[j]+p)%p; break; } else { w[i*prime[j]]=w[i]*(prime[j]-1)%p;//乘以 w[prime[j]] } } } for(ll i=1;i<=n;i++) { w[i]=(w[i-1]+w[i]*h[i]%p)%p;//求 w 的前缀和 } for(ll i=1;i<=2*n;i++) { h[i]=(h[i-1]+h[i])%p;//求 f } for(ll i=1;i<=2*n;i++) { h[i]=(h[i-1]+h[i])%p;//求 g } } ll s(ll x) { return (h[2*x]-2*h[x]%p+p)%p;//求 s } ll ask(ll n) { ll ans=0,l,r; for(l=1,r;l<=n;l=r+1) { r=(n/l>=1)?min(n/(n/l),n):n; ans=(ans+(w[r]-w[l-1]+p)%p*s(n/l)%p)%p; } return ans; } int main() { ll n,k; cin>>n>>k; k%=phi;//扩展欧拉定理 isprime(n,k); cout<<ask(n)<<endl; return 0; }
\(T4\) P167. 高松灯 \(100pts\)
-
数位 \(DP\) 板子。
点击查看代码
ll a[25],f[25][180],sum=0; ll divide(ll n,ll a[]) { ll len=0; while(n) { len++; a[len]=n%10; n/=10; } return len; } ll dfs(ll pos,ll pre,ll lead,ll limit) { if(pos<=0) { return pre; } if(f[pos][pre]!=-1&&lead==0&&limit==0) { return f[pos][pre]; } ll ans=0,maxx=(limit==0)?9:a[pos],i; for(i=0;i<=maxx;i++) { ans=max(ans,dfs(pos-1,pre+i,(i==0)*lead,(i==maxx)*limit)); } return (lead==0&&limit==0)?f[pos][pre]=ans:ans; } ll ask(ll n) { ll len=divide(n,a); return dfs(len,0,1,1); } int main() { ll n; cin>>n; memset(f,-1,sizeof(f)); cout<<ask(n)<<endl; return 0; }
-
最终答案只会来自两种情况,一种是原数,一种是首位放 \(1\) 其余全是 \(9\) ,二者取 \(\max\) 即可。
总结
- 赛时历程:先溜了一眼题, \(T1\) 直接弃掉, \(T2\) 之前做过但细节有点多, \(T3\) 可以骗点分, \(T4\) 之前做过类似的且几乎是数位 \(DP\) 纯板子。遂先写 \(T4\) ,因为太过着急导致少打了个负号,少搜了许多状态,花 \(20 \min\) 才调出来;然后写 \(T2\) ,式子因为之前写的时候有点麻烦,遂写了个简单点的,但还是在调细节,调了 \(1h\) ;接着是 \(T3\) ,推到最后发现漏了一个 \(\gcd(i,j)=1\) 导致预处理直接死掉,交了个暴力上去; \(T1\) 特判了两种情况。
- \(T2\) 枚举 \(10^{k}\) 时炸
long long
了,挂了 \(5pts\) 。 - \(T3\) 暴力预处理 \(\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}[\gcd(i,j)=1] \times (i+j)^{k}\) 时空间开大了,再次 \(MLE\) ,挂了 \(20pts\) 。
后记
-
难度不单调递增。
-
因赛时能过 \(T1\) 太过逆天,所以奖励也很逆天。
-
@joke3579 学长让 @int_R 上台评价这场比赛,还开玩笑说要不少于六百字,且还拍视频给 @worldvanquisher 。
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/18328194,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。