中考后刷题补题合集

news/2024/9/28 6:07:22

T1(莫队,增量式维护答案)

https://www.luogu.com.cn/problem/P1494
1731。
看上一篇总结的莫队。双倍经验。

QAQ
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>using namespace std;typedef long long LL;
typedef pair<LL, LL> PLL;
const int N = 50010;int n, m, L;
int cnt[N], w[N];
struct Query { int l, r, bcnt, id;
bool operator< (const Query& W) const{if (bcnt != W.bcnt) return bcnt < W.bcnt;return r > W.r;
}}q[N]; 
PLL ans[N];void work(int x, int type, LL& res)
{res -= (LL)cnt[x] * (cnt[x] - 1) / 2; //无论加还是减,之前的都没了cnt[x] += type;if (cnt[x] >= 2) res += (LL)cnt[x] * (cnt[x] - 1) / 2;
}LL gcd(LL a, LL b)
{return b ? gcd(b, a % b) : a;
}int main()
{scanf("%d%d", &n, &m);L = sqrt(n);for (int i = 1; i <= n; i ++ ) scanf("%d", &w[i]);for (int i = 1; i <= m; i ++ ){int l, r;scanf("%d%d", &l, &r);q[i] = {l, r, (l - 1) / L + 1, i};}sort(q + 1, q + m + 1);LL res = 0;for (int i = 1, l = 1, r = 0; i <= m; i ++ ){while (l > q[i].l)  -- l, work(w[l], 1, res);while (r < q[i].r)  ++ r, work(w[r], 1, res);while (l < q[i].l) work(w[l], -1, res), l ++ ;while (r > q[i].r) work(w[r], -1, res), r -- ;if (!res) ans[q[i].id] = {0, 1};else{LL a = q[i].r - q[i].l + 1;LL k = gcd(res, a * (a - 1) / 2);ans[q[i].id] = {res / k, a * (a - 1) / 2 / k};}}for (int i = 1; i <= m; i ++ )if (!ans[i].first) puts("0/1");else printf("%lld/%lld\n", ans[i].first, ans[i].second);return 0;
}

T2(斜率优化dp模板,费用提前计算思想)

814。
https://www.acwing.com/problem/content/303/
首先做出dp.dp完了优化转移

由于我们知道分了几批就是为了算启动代价,不如直接累加到值里面,把后面的提前算了!
费用提前计算:把以后启动的代价都算进来。

这样状态就变成了:f[i],前i个物品选若干次,已经考虑当前批代价和对以后启动时间的代价的最小值。

还可以这样理解:

。这样,以c为横坐标,f为纵坐标,我们发现这是个斜率相同的直线,现在所决策应该是一个点,这个点所形成的的直线的截距最小。这是啥?直接凸包维护就好了,取的值就是遍维护凸包边算就行,最后加进来(加进来一定横坐标单调)。

扩展:t不单调(也就是t可以为负):那就没有办法利用询问斜率的单调性了,只能维护整个凸包。(原先可以边问边删),二分就好。c不单调:那就套一层平衡树维护凸包。

QAQ
#include <iostream>
#include <algorithm>
#include <cstring>using namespace std;typedef long long LL;const int N = 3e5 + 10;int n, s;
LL c[N], t[N];
LL f[N];
int q[N];int main()
{scanf("%d%d", &n, &s);for (int i = 1; i <= n; i ++ ){scanf("%lld%lld", &t[i], &c[i]);t[i] += t[i - 1];c[i] += c[i - 1];}int hh = 0, tt = 0;q[0] = 0;for (int i = 1; i <= n; i ++ ){while (hh < tt && (f[q[hh + 1]] - f[q[hh]]) <= (t[i] + s) * (c[q[hh + 1]] - c[q[hh]])) hh ++ ;int j = q[hh];f[i] = f[j] - (t[i] + s) * c[j] + t[i] * c[i] + s * c[n];while (hh < tt && (f[q[tt]] - f[q[tt - 1]]) * (c[i] - c[q[tt - 1]]) >= (f[i] - f[q[tt - 1]]) * (c[q[tt]] - c[q[tt - 1]])) tt -- ;q[ ++ tt] = i;}printf("%lld\n", f[n]);return 0;
}

T3(反悔式贪心及部分贪心的证明)

我的比赛思路:
U题,首先考虑dp,肯定开的状态是:前i个,时间,收益。时间当然开不下,考虑优化。发现对于每一秒,都必须打一只。这样大于i的时间就没有用了,一定不优。这样按照当前选不选就能做。不过复杂度是n^2。只能贪心。考虑留一维。必须有时间,于是留下时间t,就是每个物品看看咋选,发现d>t的没必要考虑,只需要留到后面打掉就行了。如果后面打掉不优,还可以调整。这样我排个序,开了个堆维护当前最优的。然后也是写挂了。
V题,消除一定是区间,考虑区间dp。转移就是要么中间消掉,再打两边,要么枚举断点。没错又写挂了。
W题,安排m个树上不相交路径,求最小值最大。当然二分,然后后面咋做没想好。感觉好像可以把所有路径按照根节点分类?写了45分的链和菊花分。
X题,我的想法,可能一定是删掉原图中某些冗余边?然而对于如何判断这个冗余和上述结论,都没想太好。
在做前两题的时候,u题写了个对拍,是a的。不知道怎么挂了。v题自己也是手捏了很多数据,然而也是wa。


我的思路,维护前i个老鼠的最优解。
实际上要求的其实就是最优解唯一。


两个极值点,一定能分出高下。
我们的贪心就是不断探极值的情况。

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>using namespace std;typedef long long LL;const int N = 100010;int n;
struct Node { int d, v;
bool operator< (const Node& W) const
{if (d != W.d) return d < W.d;return v > W.v;
}
} a[N];
priority_queue<int, vector<int>, greater<int> > q;
LL res;
int main()
{scanf("%d", &n);for (int i = 1; i <= n; i ++ ) scanf("%d%d", &a[i].d, &a[i].v);sort(a + 1, a + n + 1);int tim = 1;q.push(a[1].v);res += a[1].v; //特判,防止里面没东西,一定加进去for (int i = 2; i <= n; i ++ ){if (tim < a[i].d) tim ++ , res += a[i].v, q.push(a[i].v);else{int t = q.top(); //取出来的过期时间一定小于i,既然他能放进去,那i也能放进去。if (t < a[i].v){q.pop();res = res - t + a[i].v;q.push(a[i].v);}}}cout << res << endl;return 0;
}

T4

区间dp。f[i][j]表示i~j最大。
决策:最后一段:f[i][j - 1]
or f[i][p]???与中间一段接上再一块消。
这里状态没办法描述了。我们考虑加一维。既然要加上一块消,我们就直接f[i][j][k],k是向右延拓k个格子和最后一段一块消除。
o。

QAQ
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>using namespace std;const int N = 110;int n, cnt;
int f[N][N][N];
int a[N], c[N], w[N];int dp(int x, int y, int k)
{if (x > y) return -0x3f3f3f3f;if (f[x][y][k]) return f[x][y][k];f[x][y][k] = max(f[x][y][k], dp(x, y - 1, 0) + f[y][y][k]);for (int i = x; i < y - 1; i ++ )if (c[i] == c[y]) f[x][y][k] = max(f[x][y][k], dp(x, i, w[y] + k) + dp(i + 1, y - 1, 0));return f[x][y][k];
}int main()
{scanf("%d", &n);for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);for (int i = 1, j = i; i <= n; i = j){j = i;while (j <= n && a[j] == a[i]) j ++ ;int len = j - i;c[ ++ cnt] = a[i];w[cnt] = len;}for (int i = 1; i <= cnt; i ++ )for (int k = 0; i + k <= n; k ++ ) //有可能处理n个,这里注意f[i][i][k] = (w[i] + k) * (w[i] + k);cout << dp(1, cnt, 0) << endl;return 0;
}

T5(树形dp,二分,树上不相交路径dp套路)

安排m个树上不相交路径,求最小值最大。有最优子结构:全局最优,子树就最优。
考虑二分判断+dp.


优化的关键在于只有一条边传上去。这使得我们可以一个个子树考虑。
子树最优嘛,要是不最优,那最多多向上的一条,所以子树多选一定不劣。那现在问题就是当前点最多贡献多少个答案?
答案就是处理传上来的这些边,排个序,贪心匹配。(为啥?最优子结构啊,当前最优就一定不劣),剩下的最大值再传上去。这样就最优了。o。


偷个懒,这里用multiset。
思想的本质
其实本质还是dp套路:f[u] = f[son] + ().(son,u之间的贡献)
只不过这里的贡献不仅仅是贡献,还要上传最大的边来维护递推。其实只要知道子树传上来最大的边,son和u的问题就变成贪心匹配的问题了。
所以优化的关键在于只有一条边传上去。这使得我们可以一个个子树考虑。
子树内的路径已经考虑完了,经过根的还没考虑呢,但是经过根的路径每个子节点最多传上来一条~,当然传最大的,我们维护一下就行了。

T6(传递闭包,最优决策分析,贪心,无向图拓扑考虑)

最优解唯一,就可以不断探向最优解了,不断维护局部最优解。考虑递推。

无环图按拓扑排序考虑算是常用思路吧。
做法已经写的很明白了。看思路,首先拓扑图,这样我们就能想到,如果只维护后面的最值就可以了,这样就可以递推了。发现最优解唯一
ok,我们考虑保留u的邻边,我们可以想到,编号小的理应不选就没得选了,因此我们考虑不断取小的。
按v从小到大,如果当前过不去,后面的只能更往后,不可能走回到v来
ok,那这样递推就解决了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>using namespace std;const int N = 1010;int res, n, m;
bool g[N][N];
bool s[N][N];
int main()
{scanf("%d%d", &n, &m);for (int i = 1; i <= n; i ++ ) g[i][i] = true;while (m -- ){int a, b;scanf("%d%d", &a, &b);s[a][b] = true;}int res = 0;for (int i = n; i; i -- )for (int j = i + 1; j <= n; j ++ )if (s[i][j] && !g[i][j]) //能加{res ++ ;for (int k = j; k <= n; k ++ )g[i][k] |= g[j][k];}cout << res << endl;return 0;
}

T7(树上最小支配集模板)


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hjln.cn/news/46996.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

go gin web服务器使用fvbock/endless优雅地重启或停止

gin使用fvbock/endless gin 正常使用注册路由时: package mainimport "github.com/gin-gonic/gin"func main() {r := gin.Default()r.GET("/ping", func(c *gin.Context) {c.JSON(200, gin.H{"message": "pong",})})r.Run() // 监听并…

typroa图片上传脚本

typroa的图片上传脚本,针对Telegraph-Image项目,适用于macOS和Linux系统。安装json处理器macOSbrew install jqLinux:# Debian/Ubuntu apt install jq -y​ 脚本配置 编辑脚本,在以下位置填入你的图床url: # 自定义URL部分 base_url=""注意:网址url后不需要加 …

HTML中的文本居中

本文将详细介绍如何在HTML中实现文本居中,包括使用不同的HTML标签和CSS属性来达到这一目的。HTML中的文本居中 参考:html center text 在网页设计中,文本居中是一种常见的布局需求,用于提高页面的美观性和用户体验。HTML(HyperText Markup Language)作为构建网页内容的标…

HbuilderX 4.15版本 text标签不能用v-html渲染,会失效

如题,注意uni-notice-bar组件,里面用了标签v-html渲染,所以4.15版本的uni-notice-bar组件不要用,坑

论文阅读:T-RAG: LESSONS FROM THE LLM TRENCHES

T-RAG: LESSONS FROM THE LLM TRENCHES(https://arxiv.org/abs/2402.07483) https://github.com/jiangnanboy/paper_read_note一.概述大型语言模型(llm)越来越多地应用于各个领域,包括对私有企业文档的问答,其中数据安全性和鲁棒性至关重要。检索增强生成(retrieve - augment…

论文阅读:UniMS-RAG: Unified Multi-Source RAG for Personalised Dialogue

UniMS-RAG: Unified Multi-Source RAG for Personalised Dialogue(https://arxiv.org/abs/2401.13256) https://github.com/jiangnanboy/paper_read_note一.概述本研究探讨如何分解RAG过程,加入多文件检索、记忆和个人信息等元素。大型语言模型(llm)在自然语言任务中表现出色…

Windows defender:威胁服务已经停止

前言 最近遇到了一件棘手的事情,Windows defender无法启动,Windows更新失败。 我是发现电脑的好多文件被劫持,图片,excel表格,pdf文档,好多文件后缀被改为.locked,想解锁得花费0.1bit,大概5万元。 网上的操作挺多的,又是命令行又是搞注册表的,没啥卵用。 环境 版本:…

学习记录

1. 用户注册用户可以通过注册功能创建自己的账户。注册信息包括以下内容: - 用户ID(学号) - 用户名(姓名) - 手机号码 - 用户单位(班级)首次注册后,用户的姓名将被记录,无需每次输入。2. 设定每周学习目标每周一,用户可以设定学习目标,包括具体的任务目标,如完成数…