你硕德对,蛋柿现在是日记时间。
洛谷讨论区昨天爆炸了,究其原因是洛谷国际站有人发 nc 内容,直接被罚了 万。重要的是:

他的注册资本都才 万。
然后今天早上来了一个 综合训练。其实就是 IOI 赛制的模拟赛,只不过有 题,从做题的顺序来说吧。
Count The Bits↗
这道题是场切的,就是一道简单的不能再简单的数位 dp。还是说一下。
先想状态。设 表示填到了第 位,总共有 个 ,这个数 时的方案数。我们直接开始记搜。搜索边界就是当 时,如果 就 return cnt 否则 return 0。
放一下简单至极的代码:
#include<bits/extc++.h>#pragma GCC optimize(2)#pragma GCC target("avx")using namespace std;typedef long long ll;const ll mod = 1000000009;int k,b;ll dp[130][130][1005];ll dfs(int pos,int cnt,int p){ if (~dp[pos][cnt][p]) return dp[pos][cnt][p]; if (pos == b) return p == 0 ? cnt : 0; ll ret = 0; for (int i = 0; i < 2; i++) ret = (ret + dfs(pos + 1,cnt + i,(p << 1 | i) % k)) % mod; return dp[pos][cnt][p] = ret;}signed main(){ scanf("%d%d",&k,&b); memset(dp,0xff,sizeof dp); printf("%lld",dfs(0,0,0)); return 0;}之前考试有一道这样的题,但是那道题的 很大,大到 数组存不下的地步,但是我们发现, 越大暴力越快。当 存不下时,我们就可以直接上暴力了。
Space Station↗
这道题也是一道搜索题。直接上记搜。但是我上午实在是太颓废了导致根本没有想这道题。
其实很简单。我们看 ,想到用桶。(其实我赛时想到的是 ,就存得下 数组,然后就这么的错了) 表示 的出现次数。对 算哈希用来记忆化。然后就这么做完了。
放下代码:
#include<bits/extc++.h>#define int long longusing namespace std;typedef unsigned long long ull;const int maxn = 1e5 + 5;const int mod = 1e9 + 7;const int base = 97;int n;int cnt[55],cnt0,_max;int a[maxn];int fac[maxn];__gnu_pbds::gp_hash_table<ull,int>dp;void init(int up = 1e5){ fac[0] = 1; for (int i = 1; i <= up; i++) fac[i] = fac[i - 1] * i % mod;}inline ull hsh(){ ull ret = 0; for (int i = 50; i >= 0; i--) ret = ret * base + cnt[i]; return ret;}int dfs(int sum,int stp){//sum表示现在数字的和,stp表示还剩多少步 if (!stp)//走完了就直接return return 1; if (sum >= _max)//如果现在的和已经大于最大的数了,那么剩下的随便走,有stp的阶乘种情况。 return fac[stp]; ull hs = hsh();//哈希 int ret = 0; if (dp.find(hs) != dp.end())//如果搜过了 return dp[hs]; for (int i = 1; i <= sum; i++) { if (cnt[i]) { cnt[i]--; ret = (ret + (cnt[i] + 1) * dfs(min(_max,sum + i),stp - 1) % mod) % mod; cnt[i]++; } } return dp[hs] = ret;//记忆化}signed main(){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); init(); cin >> n >> a[0]; for (int i = 1; i <= n; i++) { cin >> a[i]; cnt[a[i]]++; cnt0 += (a[i] == 0); _max = max(_max,a[i]); } int ans = dfs(a[0],n - cnt0); for (int i = n; i > n - cnt0; i--) ans = ans * i % mod; cout << ans; return 0;}Sum of Numbers↗
我们先感性理解,每一段肯定是长度差不多的。设 ,那么每一段的长度肯定不会超过 ,我们就可以按照这个来 dp 了。
code:
#include<bits/extc++.h>#pragma GCC optimize(2)#pragma GCC optimize(3)#pragma GCC target("avx")#define int long longusing namespace std;const int maxn = 2e5 + 5;//数组开小调了一下午int n,k,len;bool vis[maxn];string s;struct long_int//这个高精度真的写死人了{ static const int base = 1e18; static const int wid = 18; vector<int>val; long_int(int len = 0){val.resize(len,0);} long_int(const string &s) { int it = s.size(); while ((it - wid) >= 0) val.push_back(stoll(s.substr(it -= wid,wid))); if (it > 0) val.push_back(stoll(s.substr(0,it))); } friend ostream &operator<<(ostream &out,const long_int &x) { if (x.val.empty()) return out << '0'; out << x.val.back(); for (int i = x.val.size() - 2; i >= 0; i--) out << setw(wid) << setfill('0') << x.val[i]; return out; } friend long_int operator+(const long_int &x,const long_int &y) { long_int ret(max(x.val.size(),y.val.size())); int f = 0,len = ret.val.size(),lenx = x.val.size(),leny = y.val.size(); for (int i = 0; i < len; i++) { if (i >= lenx) ret.val[i] = y.val[i] + f; else if (i >= leny) ret.val[i] = x.val[i] + f; else ret.val[i] = x.val[i] + y.val[i] + f; if (ret.val[i] >= base) { f = ret.val[i] / base; ret.val[i] %= base; } else f = 0; } if (f) ret.val.push_back(f); return ret; } friend bool operator<(const long_int &x,const long_int &y) { if (x.val.size() ^ y.val.size()) return x.val.size() < y.val.size(); for (int i = x.val.size() - 1; i >= 0; i--) if (x.val[i] ^ y.val[i]) return x.val[i] < y.val[i]; return 0; }}dp[maxn];void solve(){ cin >> n >> k >> s; fill(vis + 1,vis + n + 1,0); len = n / (k + 1) + 2; for (int x = 0; x <= k; x++) { for (int i = n; i >= max(1ll,n - len * (k - x)); i--) { for (int j = max(0ll,i - len); j <= min(x * len,i - 1); j++) { if (!j || vis[j]) { long_int tmp = dp[j] + s.substr(j,i - j); if (!vis[i] || tmp < dp[i]) { dp[i] = tmp; vis[i] = 1; } } } } } cout << dp[n] << '\n';}signed main(){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); int t; cin >> t; while (t--) solve(); return 0;}然后颓废的一天就这么的结束了。今天晚上好像高三的返校,而我们比他们早一天返校,我们还跟他们一起放假。
比高三的放的还短,这辈子有了
Thanks for reading!
