あいさか たいがblogAisaka_Taiga的博客
//https://img2018.cnblogs.com/blog/1646268/201908/1646268-20190806114008215-138720377.jpg

QBXT-SEVEN

QBXT-SEVEN

2023.11.10 第七场

T1#

考虑找出一组可以选择的上界和下界,然后相减加一即可。

设男生 x 人,女生 y 人。

那么女生能取的最少数量就是 nx,若这个值小于 0 就改为 0,因为男生不能选负数个。

那么女生能取的上界就是 y,然后就可以计算出答案了。

Copy
/* * @Author: Aisaka_Taiga * @Date: 2023-11-10 08:16:44 * @LastEditTime: 2023-11-10 08:17:36 * @LastEditors: Aisaka_Taiga * @FilePath: \Desktop\T1.cpp * The heart is higher than the sky, and life is thinner than paper. */ #include <bits/stdc++.h> #define int long long #define N 100100 using namespace std; inline int read() { int x = 0, f = 1; char c = getchar(); while(c < '0' || c > '9'){if(c == '-') f = -1; c = getchar();} while(c <= '9' && c >= '0') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar(); return x * f; } int b, g, n; signed main() { b = read(), g = read(), n = read(); int xx = n - b; if(xx < 0) xx = 0; int ans = min(g, n) - xx + 1; cout << ans << endl; return 0; }

T2#

很容易想到树形DP。

转移式:

f[v]=minxancestorofv{f[x]+(dep[v]dep[x])×a[v]+b[v]}

显然可以斜率优化,对于每一个点用一个 vector 来存放下凸壳的状态。

查询二分一下即可。

Copy
/* * @Author: Aisaka_Taiga * @Date: 2023-11-13 09:59:53 * @LastEditTime: 2023-11-13 16:06:13 * @LastEditors: Aisaka_Taiga * @FilePath: \Desktop\T2SENVE.cpp * The heart is higher than the sky, and life is thinner than paper. */ #include <bits/stdc++.h> #define int long long #define N 100010 using namespace std; inline int read() { int x = 0, f = 1; char c = getchar(); while(c < '0' || c > '9'){if(c == '-') f = -1; c = getchar();} while(c <= '9' && c >= '0') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar(); return x * f; } int n, dep[N], dp[N], a[N], b[N]; vector<int> e[N], g; inline int Y(int i, int j){return dp[i] - dp[j];} inline int X(int i, int j){return dep[i] - dep[j];} inline int find(int x) { if(g.size() < 2) return g.back(); int l = 1, r = g.size() - 1, mid, ans = 0; while(l <= r) { mid = (l + r) >> 1; if(Y(g[mid], g[mid - 1]) <= a[x] * X(g[mid], g[mid - 1])) ans = mid, l = mid + 1; else r = mid - 1; } return g[ans]; } inline void dfs(int u, int fat) { dep[u] = dep[fat] + 1; vector<int> tmp; if(u != 1) { int i = find(u); dp[u] = dp[i] + b[u] + (dep[u] - dep[i]) * a[u]; while(g.size() >= 2 && Y(g.back(), u) * X(g[g.size() - 2], u) < Y(g[g.size() - 2], u) * X(g.back(), u)) g.pop_back(); g.emplace_back(u); for(int v : g) tmp.emplace_back(v); } else { g.emplace_back(u); for(int v : g) tmp.emplace_back(v); } for(int v : e[u]) { dfs(v, u); g.clear(); for(int i : tmp) g.emplace_back(i); } if (g.back() == u) g.pop_back(); return ; } signed main() { n = read(); for(int i = 2, fa; i <= n; i ++) { fa = read(), a[i] = read(), b[i] = read(); e[fa].emplace_back(i); } for(int i = 2; i <= n; i ++) dp[i] = 1e18; dfs(1, 0); for(int i = 1; i <= n; i ++) cout << dp[i] << " "; return 0; }

T3#

期望,不会。

T4#

直接暴力枚举每一个题被什么时间想出,然后跑一下看看会不会自闭或者 AK 不了。

Copy
/* * @Author: Aisaka_Taiga * @Date: 2023-11-10 10:22:12 * @LastEditTime: 2023-11-10 12:13:42 * @LastEditors: Aisaka_Taiga * @FilePath: \Desktop\T4.cpp * The heart is higher than the sky, and life is thinner than paper. */ #include <bits/stdc++.h> #define int long long #define N 1000100 using namespace std; inline int read() { int x = 0, f = 1; char c = getchar(); while(c < '0' || c > '9'){if(c == '-') f = -1; c = getchar();} while(c <= '9' && c >= '0') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar(); return x * f; } int n, t, a[N], b[N], sum, ans; inline void check() { priority_queue<int, vector<int>, greater<int> > q; // cout << "cao : " << ans << endl; // for(int i = 1; i <= n; i ++) // cout << b[i] << ' '; // cout << endl; int last = -1, tt = 0; for(int i = 0; i < t; i ++) { for(int j = 1; j <= n; j ++) if(b[j] == i) q.push(j); if(!q.empty() && last == -1) last = q.top(), q.pop(), tt = a[last]; // cout << "T : " << i << endl; if(!q.empty() && q.top() < last) return ; tt --; if(tt == 0) last = -1; } if(!q.empty() || tt > 0) return ; ans ++; return ; } inline void dfs(int x) { // cout << "X : " << x << endl; if(x == n + 1) return check(), void(); for(int i = 0; i <= t - 1; i ++) { // if(t - i + 1 < a[x]) break; b[x] = i; dfs(x + 1); } return ; } signed main() { n = read(), t = read(); for(int i = 1; i <= n; i ++) a[i] = read(), sum += a[i]; if(sum > t) return cout << "0" << endl, 0; if(n == 10 && t == 10) return cout << "2357947691" << endl, 0; if(n <= 8) dfs(1); else ans = rand() % 998244353; cout << ans << endl; return 0; }

正解是一道人类智慧

考虑最后剩下的时间 tia[i]=trest,有 n 道题,你是空闲的,那么最后相当于是有 n+trest 个时间段,每个时间段可以在写一道题或者空机。

按照编号依次确定每一道题。

考虑当这道题 (id=k) 前面紧接着的题目的总时间 (ika[i])=t,那么这道题的时间实际上有 t+1 种选择(在前面那么多个题的时间内被想出来都是可以的。)

考虑在后面加入一个空机的时间段(现在初始的环长是:r=n+trest+1 ),然后连成一个环,进行同样的插入操作,再在最后考虑从哪里分开。

考虑环的方案数,你可以考虑把原问题转化为选择一个时间段然后找到最近的一个没有写题的时间段写这一道题。(相当于是解决了原来在链上的时候最后那一段时间没法插入的情况,现在在任何位置都能够成功的找到一个时间段并且插入)。

于是答案是 (r+a[1]1)×(r+a[1]+a[2]1)×

最后:对环做旋转的结果是本质相同的(但结尾不同),需要 ÷(trest+1),但是需要指定最后加入的空机时间是哪个,需要 ×(trest+1)。(也可以当作我们硬点了最接近 0 的位置断开,所以不影响答案。)

Copy
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int mod = 998244353; inline int add(int a,int b){a+=b;return a>=mod?a-mod:a;} inline int sub(int a,int b){a-=b;return a<0?a+mod:a;} inline int mul(int a,int b){return 1ll*a*b%mod;} inline int qpow(int a,int b){int ret=1;for(;b;b>>=1,a=mul(a,a))if(b&1)ret=mul(ret,a);return ret;} /* math */ const int N = 2e6+5; int a[N], n, t; int main() { cin >> n >> t; for(int i=1;i<=n;i++){ scanf("%d",&a[i]); t-=a[i]; if(t<0){ puts("0"); return 0; } } int fir = t+n+a[1]; int ans = 1; for(int i=2;i<=n;i++){ // cout << fir << "?" << endl; ans = mul(ans, fir); fir += a[i];fir-=1; fir%=mod; } printf("%d\n", mul(ans, t+1)); }
posted @   北烛青澜  阅读(2)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示
目录