[CSP-S模拟测试]:时间机器(贪心+set)
题目描述
作为一名天才科学家,$Kurisu$已经设计出了时间机器的构造。
根据$Kurisu$的构想,时间机器中有$n$种需要放置电阻的节点,第$i$种节点有$s_i$个,其电压$U$的变动范围是${low}_i\leqslant U\leqslant {high}_i$。
现在有$m$种电阻,第$i$种电阻有$k_i$个,第$i$种电阻能正常工作时,电压$U'$需要满足$l_i\leqslant U'\leqslant r_i$。第$i$种电阻能放置在第$j$种节点上,当且仅当$l_i\leqslant {low}_j\leqslant {high}_j\leqslant r_i$。
现在$Kurisu$想要确认她的构想能不能实现,即是否能在所有节点上放置合适的电阻。
输入格式
第一行一个整数$T$,表示数据组数。
每组数据的第一行有两个整数$n,m$,表示节点和电阻的种类数。
接下来$n$行,每行三个整数${low}_i,{high}_i,s_i$,描述一种结点。
接下来$m$行,每行三个整数$l_i,r_i,k_i$,描述一种电阻。
输出格式
输出共$T$行,每行一个字符串,若可以实现则输出$"Yes"$(不包含引号),否则输出$"No"$。
样例
样例输入:
3
2 2
1 4 2
3 5 1
1 4 2
2 5 1
3 2
1 3 1
2 4 1
3 5 1
1 3 2
2 5 1
2 2
1 2 2
1 2 1
1 2 1
1 2 2
样例输出:
Yes
No
Yes
数据范围与提示
保证$1\leqslant {low}_i\leqslant {high}_i\leqslant {10}^9,1\leqslant l_i\leqslant r_i\leqslant {10}^9,1\leqslant k_i,s_i\leqslant {10}^9,T\leqslant 50,1\leqslant n,m\leqslant 5\times {10}^4$。
记$\sum n$为一个测试点中所有$n$的总和,记$\sum m$为一个测试点中所有$m$的总和,则$\sum n,\sum m\leqslant 4\times {10}^5$。
各个测试点还满足如下约束:
题解
考虑贪心。
将电阻个节点均按左端点排序,按排序考虑每一种节点,每次贪心地选择左端点在该节点左侧的电阻中,右端点在该节点右侧且尽量靠近该节点右侧的电阻。
考虑如何优化。
利用$set$维护当前左端点符合条件的电阻的右端点即可。
时间复杂度:$\Theta((n+m)\log m+n\log n)$。
期望得分:$100$分。
实际得分:$100$分。
数据范围
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #include<bits/stdc++.h> using namespace std; struct rec{ int l,r,s;}a[50001],b[50001]; struct node{ int first,second;}; int n,m; set <node> s; bool cmp(rec a,rec b){ return a.l<b.l;} bool operator < (node a,node b){ return a.first<b.first;} int main() { int T;scanf( "%d" ,&T); while (T--) { scanf( "%d%d" ,&n,&m); s.clear(); for ( int i=1;i<=n;i++)scanf( "%d%d%d" ,&a[i].l,&a[i].r,&a[i].s); for ( int i=1;i<=m;i++)scanf( "%d%d%d" ,&b[i].l,&b[i].r,&b[i].s); sort(a+1,a+n+1,cmp); sort(b+1,b+m+1,cmp); s.insert((node){2002092300,0}); for ( int i=1,j=1;i<=n;i++) { while (b[j].l<=a[i].l&&j<=m) s.insert((node){b[j].r,j++}); node flag=(node){a[i].r,0}; while (a[i].s) { flag=*s.upper_bound(flag); if (flag.first==2002092300) break ; int t=min(b[flag.second].s,a[i].s); b[flag.second].s-=t;a[i].s-=t; if (!b[flag.second].s)s.erase(flag); } if (a[i].s){puts( "No" ); goto nxt;} } puts( "Yes" ); nxt:; } return 0; } |
rp++
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步