220906 总结
220906 总结
时间有点短,做到后面稍微有点慌
怎么就想不到应该用什么算法呢。。。
赛时估计:
赛后测试:
赛后一看,还真没难题
T1 购物
直接模拟即可
T2 第 k 小
想的是将所有区间排序,顺着区间统计数量,该区间结束就在下一个区间的这个位置接着跑
但是值域
做的时候一直在想怎么缩小值域去统计结果(
最后打了个暴力就跑路了
应该但没意识到这个答案具有二分性质,即小于第 (什么废话
但是一看题解就发现了。。。呜
令
check
的时候扫一遍所有区间统计小于等于
如果
#include<bits/stdc++.h> using namespace std; const int maxN = 1e5; struct Segment { int l, r; friend bool operator < (Segment A, Segment B) { if (A.l != B.l) return A.l < B.l; return A.r > B.r; } } A[maxN]; int N, K; bool check(int k) { int cnt = 0; for (int i = 1; i <= N; i++) { if (A[i].l <= k) cnt += min(k, A[i].r) - A[i].l + 1; } return cnt >= K; } int main() { freopen("thekth.in", "r", stdin); freopen("thekth.out", "w", stdout); scanf("%d", &N); for (int i = 1; i <= N; i++) { int l, r; scanf("%d%d", &A[i].l, &A[i].r); } scanf("%d", &K); int l = -1e9; int r = 1e9; int ans = 0; while (l <= r) { int mid = (l + r) >> 1; if (check(mid)) { ans = mid; r = mid - 1; } else l = mid + 1; } printf("%d", ans); return 0; }
T3 最大半连通子图
考的时候在要不要略过 T2 之间摇摆不定导致只剩半小时写这道题了...寄!
半小时糊了一个实际上思路正确但被我写挂了的TLE做法
将所有的 scc
缩成一个点,那么最大半联通子图实际上就是找缩完点形成的这张 DAG
上的最长链
使用拓扑排序更新最长链的长度,如果成功更新,那么重置长度最大值及个数;如果当前长度与最长链长度相同,则更新最长链个数。
Lg 上这么就能过了,但是 Lemon 测的时候还得卡卡常才能过(
#include<bits/stdc++.h> using namespace std; const int maxN = 1e5 + 10; int MOD; vector<int> G[maxN]; int N, M; stack<int>s; int ins[maxN]; int dfn[maxN]; int low[maxN]; int cnt = 0; int sccNum = 0; int sccSiz[maxN]; int scc[maxN]; void tarjan(int u) { cnt++; dfn[u] = cnt; low[u] = cnt; s.push(u); ins[u] = 1; for (auto i : G[u]) { int v = i; if (!dfn[v]) { tarjan(v); low[u] = min(low[u], low[v]); } else if (ins[v]) { low[u] = min(low[u], dfn[v]); } } if (low[u] == dfn[u]) { ins[u] = 0; sccNum++; scc[u] = sccNum; sccSiz[sccNum] = 1; while (s.top() != u) { int sT = s.top(); scc[sT] = sccNum; ins[sT] = 0; sccSiz[sccNum]++; s.pop(); } s.pop(); } return; } vector<int> G2[maxN]; int inD[maxN]; inline void reBuid() { unordered_set<long long> S; for (int i = 1; i <= N; i++) { for (auto j : G[i]) { long long H = 100000ll * scc[i] + scc[j]; if (S.count(H)) continue; if (scc[i] != scc[j]) { G2[scc[i]].push_back(scc[j]); inD[scc[j]]++; } S.insert(H); } } } int dp[maxN]; int num[maxN]; inline void Topo() { queue<int> Q; for (int i = 1 ; i <= sccNum; i++) { if (inD[i] == 0) Q.push(i); dp[i] = sccSiz[i]; num[i] = 1; } while (!Q.empty()) { int u = Q.front(); Q.pop(); for (auto i : G2[u]) { if (dp[i] < dp[u] + sccSiz[i]) { dp[i] = dp[u] + sccSiz[i]; num[i] = num[u]; } else if (dp[i] == dp[u] + sccSiz[i]) { num[i] = (num[u] % MOD + num[i] % MOD) % MOD; } if (--inD[i] == 0) Q.push(i); } } } int main() { ios :: sync_with_stdio(false); freopen("semi.in", "r", stdin); freopen("semi.out", "w", stdout); cin >> N >> M >> MOD; for (int i = 1; i <= M; i++) { int u, v; cin >> u >> v; G[u].push_back(v); } for (int i = 1; i <= N; i++) if (!dfn[i]) tarjan(i); reBuid(); Topo(); int dis = -1; int ans = -1; for (int i = 1; i <= sccNum; i++) { if (dp[i] > dis) { dis = dp[i]; ans = num[i]; } else if (dp[i] == dis) { ans = (ans % MOD + num[i] % MOD) % MOD; } } printf("%d\n%d", dis, ans); return 0; }
简单总结
-
稳一点
-
觉得算法不行的时候考虑考虑题目具有的性质
-
别急,急也没用.jpg
-
码力不太够,表现在代码细节出现令人智熄的离谱错误
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库