论如何 AK WFYZ公益班测试-20240330

· · 题解

晚了半个点参赛,因为此前 vp 了上一场 CF Div.4(AK)

C 没测第二个样例,刚好题目翻译有问题(事实不应该去重,但翻译成了去重),怒挂 50。
D 题我看最后一个点 n=2000,就以为 n \le 2000,事实上 n \le 2\cdot 10^5,挂 40。 F 题写的正解,然而要求的值看错了,导致没调出来,哎。

A - CF598A

套公式直接算。

B - CF598B

同一个长度为 len 的区间执行 k 次和执行 k \mod len 次效果是一样的,可以以此在每次操作中快速计算出每个字符新的位置。
注意到操作次数很少,模拟就可以。

C - CF598D

bfs 就行了,注意本题洛谷翻译是错的,应该按照题目警示贴来。

D - P2846

线段树维护,每个节点记录本区间答案,以及一个 lazytag 代表本区间灯状态是否反转。

E - CF461B

设状态 dp_{u,1/0},代表 u 为根的子树,u 所在的连通块有一个/没有黑色节点,且其他连通块合法的方案数。

F - CF598E

转移十分的暴力,枚举分割点,将其分割成两个小巧克力,并枚举第一个小巧克力和第二个小巧克力各贡献多少大小的巧克力(用来凑成大小为 $k$ 的巧克力) 然后没啥好说的,自认为本蒟蒻的代码还是比较好懂的。 ```cpp #include <bits/stdc++.h> using namespace std; #define FOR(i,a,b) for(int i=a;i<=b;i++) #define REP(i,a,b) for(int i=a;i>=b;i--) #define pb push_back #define mkpr make_pair typedef long long ll; typedef pair<int,int> pii; typedef pair<ll,ll> pll; template<class T> void ckmn(T& a,T b){ a=min(a,b); } int T; const int maxn=55; ll dp[maxn][maxn][maxn]; // chang,kuan 的巧克力搞出 k ll dfs(int chang,int kuan,int k){ if(k==0)return 0; if((chang==1&&kuan==1)&&(k!=1))return 1e18; if(dp[chang][kuan][k]<dp[0][0][0])return dp[chang][kuan][k]; if(k>chang*kuan){return 1e18;} if(k==chang*kuan){return 0;} FOR(lef,0,k){ FOR(i,1,chang-1){ ckmn(dp[chang][kuan][k],dfs(i,kuan,lef)+dfs(chang-i,kuan,k-lef)+kuan*kuan); } FOR(i,1,kuan-1){ ckmn(dp[chang][kuan][k],dfs(chang,i,lef)+dfs(chang,kuan-i,k-lef)+chang*chang); } } // printf("dp[%d][%d][%d] = %lld\n",chang,kuan,k,dp[chang][kuan][k]); return dp[chang][kuan][k]; } void solve(){ int n,m,k; scanf("%d%d%d",&n,&m,&k); printf("%lld\n",dfs(n,m,k)); } int main() { memset(dp,0x7f,sizeof dp); dp[1][1][1]=0; scanf("%d",&T); while(T--){ solve(); } return 0; } ```