The 2021 ICPC Asia Regionals Online Contest (I)
The 2021 ICPC Asia Regionals Online Contest (I)
写了一晚上,日…
文章目录
- 一、 A Busiest Computing Nodes
- 二、D Edge of Taixuan
- 三、F Land Overseer
- 四、I Neiborhood Search
- 五、K Segment Routing
- 六、H Mesh Analysis
- 七、B Convex Polygon
- 八、G Longest Prefix Matching
一、 A Busiest Computing Nodes
题意:有k个计算节点和n个询问,后0-n-1行每个询问给定一个节点被占用的起始时间和占用时间。最好占用第i%k个节点,若该节点被占用,则依次往后寻找节点占用,(i%k),(i+1)%k,(i+2)%k… 如果都被占用则跳过此次查询。
思路:线段树+二分.
维护区间上的最小值,即结束占用的最早时间。如果右子区间上有则二分查找右子区间,没有则二分查找左子区间.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>#define int long longusing namespace std;typedef long long ll;const int N = 100010;
int k,n;
int p[N]; // 记录占用情况. struct Tree{int l,r;int v; // 记录区间内的最小结束时间:起初均为 0
}tr[N*4];void pushup(Tree &rt,Tree &l,Tree &r){rt.v = min(l.v,r.v);
}void pushup(int u){pushup(tr[u],tr[u<<1],tr[u<<1|1]);
}void build(int u,int l,int r){tr[u] = {l,r};if(l==r){tr[u] = {l,l,0};return;}int mid = (l + r) >> 1;build(u<<1,l,mid);build(u<<1|1,mid+1,r);pushup(u);
}int query(int u,int l,int r){if(l<=tr[u].l && tr[u].r<=r) return tr[u].v; //返回v. int mid = (tr[u].l + tr[u].r) >> 1;int ans = 1e9;if(l<=mid) ans = min(ans,query(u<<1,l,r));if(r>mid) ans = min(ans,query(u<<1|1,l,r));return ans;
}void modify(int u,int x,int val){if(tr[u].l==x && tr[u].r==x){tr[u].v = val;return;}int mid = (tr[u].l + tr[u].r) >> 1;if(x<=mid){modify(u<<1,x,val);}else{modify(u<<1|1,x,val);}pushup(u);
}signed main()
{if(scanf("%lld%lld",&k,&n)){build(1,1,k);// for(int i=1;i<=5;i++){// cout << i << " " << tr[i].l << " " << tr[i].r << " " << tr[i].v << endl;
// }// 到达时间是否需要排序 不需要 The requests are given in non-decreasing order of arrival time.for(int i=0;i<n;i++){int st_time,ocupy_time;if(scanf("%lld%lld",&st_time,&ocupy_time)){if(query(1,i%k+1,k)<=st_time){ // 右子区间有 int l = i%k + 1, r = k;while(l<r){int mid = (l + r) >> 1; if(query(1,l,mid)<=st_time) r = mid;else l = mid + 1; }modify(1,l,st_time+ocupy_time);p[l] ++;}else if(i%k){ // 左子区间有 if(query(1,1,i%k)<=st_time){int l = 1, r = i%k;while(l<r){int mid = (l + r) >> 1; if(query(1,l,mid)<=st_time) r = mid;else l = mid + 1; }modify(1,l,st_time+ocupy_time);p[l] ++; }}}}int mx = 0;for(int i=1; i<=k; i++) mx = max(mx,p[i]); int cnt = 0;for(int i=1; i<=k; i++) if(mx==p[i]) cnt++;for(int i=1; i<=k; i++)if(mx==p[i]) {printf("%lld",i-1);if(--cnt) printf(" ");}}return 0;
}
二、D Edge of Taixuan
这题饶了半天,好长的题.
题意:给定一个无向图,可能存在重边,每条边存在一个边权,问在保证图连通性的前提下最长可以删除的边的长度为多少?如果整个图不连通,则输出“Gotta prepare a lesson”.
思路:想了挺久,刚开始以为是求最小生成数。可是边数太jb多了,这要全存下来最坏的情况已经超时了.
问题每次给出的是区间的 l 和 r ,在区间上作改变—>线段树.怎么写线段树成了关键。
思考这样一种思路:1. 将查询的信息储存并按照权值从大到小进行排序,在进行遍历时每次都通过线段树进行区间修改。 2. 将边权看成点权。将i和i+1之间边的权重看成点i的权重。这样在修改时相当于对区间 [l,r-1] 每个点进行修改;在查询时相当于单点查询。
这样的最小生成树的权值就是前n-1个结点的权重。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>using namespace std;typedef long long ll;
const int N = 100010;struct Edge{int l,r;int w;bool operator <(const Edge &W) const{return w>W.w;}
}e[N];struct Tree{int l,r;int m,add; //add为懒标记.
}tr[N * 4];void pushup(int u){tr[u].m = min(tr[u<<1].m,tr[u<<1|1].m);
}void pushdown(int u){Tree &rt = tr[u];Tree &l = tr[u<<1];Tree &r = tr[u<<1|1];if(rt.add){l.add += rt.add, l.m = rt.m;r.add += rt.add, r.m = rt.m;rt.add = 0;}
}void build(int u,int l,int r){tr[u] = {l,r,0,0};if(l==r){tr[u] = {l,l,0,0};return;}int mid = (l+r)>>1;build(u<<1,l,mid);build(u<<1|1,mid+1,r);pushup(u);
}int query(int u,int l,int r){if(tr[u].l>=l && tr[u].r<=r) return tr[u].m;pushdown(u);int mid = (tr[u].l + tr[u].r) >> 1;int ans = 1e9;if(l<=mid) ans = min(ans,query(u<<1,l,r));if(r>mid) ans = min(ans,query(u<<1|1,l,r));return ans;
}void modify(int u,int l,int r,int val){if(tr[u].l>=l && tr[u].r<=r){tr[u].m = val;tr[u].add = val;return;}pushdown(u);int mid = (tr[u].l + tr[u].r) >> 1;if(l<=mid){modify(u<<1,l,r,val);}if(r>mid){modify(u<<1|1,l,r,val);}pushup(u);
}int main()
{int t;scanf("%d",&t);for(int k=1;k<=t;k++){int n,m;scanf("%d%d",&n,&m);sizeof(tr,0,sizeof tr);build(1,1,n);for(int i=1;i<=m;i++) scanf("%d%d%d",&e[i].l,&e[i].r,&e[i].w);sort(e+1,e+m+1);ll sum = 0;for(int i=1;i<=m;i++){int l,r,w;l = e[i].l, r = e[i].r, w = e[i].w;modify(1,l,r-1,w);sum += ((ll)r - l + 1) * (ll)w * ((ll)(r-l)) / 2;}
// cout << sum << endl;
// for(int i=1;i<=5;i++){// cout << "节点" << i << ":" << tr[i].l << " " << tr[i].r << " " << tr[i].m << " " << tr[i].add << endl;
// }bool f = 1;for(int i=1;i<n;i++){int t = query(1,i,i);
// cout << "结点" << i << " = " << t << endl;if(!t){f = 0;break;}else{sum -= (ll)t;}}printf("Case #%d: ",k);if(f) printf("%lld",sum);else printf("Gotta prepare a lesson");if(k!=t) printf("\n");}return 0;
}
三、F Land Overseer
没啥好说的,注意b<=r 时的情况就行.
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>using namespace std;typedef long long ll;// 注意,如果b<=R时,直接从(0,0)走到(2a-R,0)即可。int main()
{int t;scanf("%d",&t);for(int i=1;i<=t;i++){int a,b,r;scanf("%d%d%d",&a,&b,&r);double d = 0.0;if(b<=r){d = 2.0*a - r;}else{d = sqrt((double)a*a + ((double)b - r)*((double)b - r)) * 2.0 - (double)r;}printf("Case #%d: ",i);printf("%.2lf",d);if(i!=t) printf("\n");}return 0;
}
四、I Neiborhood Search
文本处理.
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>
#include <cmath>using namespace std;typedef long long ll;int a[100010];void solve(){int i = 0;int s = 0;string ss;getline(cin,ss);for(int j=0;j<ss.size();j++){if(ss[j] == ' '){a[i++] = s;s = 0;continue;}s = s * 10 + (ss[j] - '0');}sort(a,a+i);int pos,r;scanf("%d%d",&pos,&r);for(int j=i-1;j>=0;j--){if(abs(a[j]-pos)<=r) printf("%d ",a[j]);}
}int main()
{int t = 1;
// scanf("%d",&t);while(t--){solve();}return 0;
}
五、K Segment Routing
题目比较难读懂,大致模拟一下即可。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>using namespace std;
const int N = 1e5 + 10, M = 2 * N;int n, m, k;
int a[N];
vector<int> p[N];
int main(){int T;cin >> T;for (int k = 1; k <= T; k ++ ) {cin >> n >> m;for (int i = 1; i <= n; i ++ ) {p[i].clear();int cnt, v;cin >> cnt;for (int j = 1; j <= cnt; j ++ ) {cin >> v;p[i].push_back(v);}}printf("Case #%d: \n", k);for (int i = 1; i <= m; i ++ ) {bool ok = false;int u, v, cnt, vis;cin >> u >> cnt;vis = u; for (int j = 1; j <= cnt; j ++ ) {cin >> v;if (v > p[vis].size() || !v) ok = true;if (ok) continue;vis = p[vis][v - 1];}if (ok) cout << "Packet Loss" << endl;else cout << vis << endl;}}return 0;
}
六、H Mesh Analysis
模拟
/*H Mesh Analysis 题意:第一行给定 n和 m 1≤N≤10000,1≤M≤21000,代表 n个点,m个element(三角形或线段)第2-n+1行,给定点的id和点的三维坐标(x,y,z)第n+2-n+2+m-1行,给定element的id和类型(102代表线段,203代表三角形),每行是element的顶点或端点坐标.下一行输入L,有L个询问最后 L 行每行输入一个id,输出该点周围的点的id和所在element 的id (感觉点的坐标没有任何用)
*/#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <set>using namespace std;struct Node1{int a,b;int id;bool operator< (const Node1 &W)const{return id<W.id;}
};struct Node2{int a,b,c;int id;bool operator< (const Node2 &w)const{return id<w.id;}
};map<Node1,int> mp1;
map<Node2,int> mp2;
map<int,int> mp3;
set<int> s1,s2;int main()
{std::ios::sync_with_stdio(false); std::cin.tie(0);double x,y,z;int id;int n,m;cin >> n >> m;for(int i=1;i<=n;i++){cin >> id >> x >> y >> z;mp3[id] = 1;}int t;int a,b,c;for(int i=1;i<=m;i++){cin >> id >> t;if(t==203){cin >> a >> b >> c;mp2[{a,b,c,id}] = 1;}else{cin >> a >> b;mp1[{a,b,id}] = 1;}}// 离线还是在线? int q;cin >> q;for(int k=1;k<=q;k++){cin >> a;s1.clear();s2.clear();for(auto x:mp1){if(x.first.a==a || x.first.b==a){s1.insert(x.first.a);s1.insert(x.first.b);s2.insert(x.first.id);}}for(auto x:mp2){if(x.first.a==a || x.first.b==a || x.first.c==a){s1.insert(x.first.a);s1.insert(x.first.b);s1.insert(x.first.c);s2.insert(x.first.id);}}cout << a << endl;cout << "[" ;int sz = s1.size();int i = 0;for(auto x:s1){i++;if(x==a) continue;cout << x;if(i!=sz) cout << ",";}cout << "]" << endl;cout << "[" ;sz = s2.size();i = 0;for(auto x:s2){i++;cout << x;if(i!=sz) cout << ",";}cout << "]";if(k!=q) cout << "\n";}return 0;
}
七、B Convex Polygon
二维几何:判断所给的点是否为凸多边形.并按顺时针顺序输出点(从最接近(0,0)的点开始输出)
若为否(三点共线或不为凸多边形)输出"ERROR".
题目实际上没有所谓的“非法”输入。
题目要判断是输入的所有点能否构成一个凸多边形,并且任意 3点不共线。
先判断点数 ≥3,然后O(n^3)暴力判断三点共线,最后求凸包判断凸包上的点是否等于总点数即可.
经典凸包,经典不会.
做出来了,感动中国,含泪来更新题解了
/*B Convex Polygon 二维几何:判断所给的点是否为凸多边形.并按顺时针顺序输出点(从最接近(0,0)的点开始输出)若为否(三点共线或不为凸多边形)输出"ERROR".
*//*
题目实际上没有所谓的 “非法 ”输入。
题目要判断是输入的所有点能否构成一个凸多边形,并且任意 3点不共线。
先判断点数 ≥3,然后O(n^3)暴力判断三点共线,最后求凸包判断凸包上的点是否等于总点数即可.
*/#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>using namespace std;const int maxn = 110;
const double eps = 1e-7;struct Point {int x, y;Point(int x = 0,int y = 0):x(x),y(y){}
};
typedef Point Vector;
Point lst[maxn];
int stk[maxn], top;
Vector operator - (Point A, Point B){return Vector(A.x-B.x, A.y-B.y);
}
int sgn(int x){if(x == 0)return 0;if(x < 0)return -1;return 1;
}
int Cross(Vector v0, Vector v1) {return v0.x*v1.y - v1.x*v0.y;
}
int Dis(Point p1, Point p2) { //计算 p1p2的 距离的平方 return (p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y);
}
bool cmp(Point p1, Point p2){ //极角排序函数 ,角度相同则距离小的在前面int tmp = sgn(Cross(p1 - lst[0], p2 - lst[0]));if(tmp > 0)return true;if(tmp == 0 && Dis(lst[0], p1) < Dis(lst[0], p2))return true;return false;
}void Graham(int n) { // n为点的个数. 下标为 0 - n-1 int k = 0;Point p0;p0.x = lst[0].x;p0.y = lst[0].y;for(int i = 1; i < n; ++i) {if( (p0.y > lst[i].y) || ((p0.y == lst[i].y) && (p0.x > lst[i].x)) ) {p0.x = lst[i].x;p0.y = lst[i].y;k = i;}}lst[k] = lst[0];lst[0] = p0;sort(lst + 1, lst + n, cmp);stk[0] = 0;stk[1] = 1;top = 2;for(int i = 2; i < n; ++i) {while(top > 1 && Cross(lst[stk[top - 1]] - lst[stk[top - 2]], lst[i] - lst[stk[top - 2]]) <= 0)--top;stk[top] = i;++top;}return;
}
//typedef Point Vector;
//Vector operator - (Point A, Point B){// return Vector(A.x-B.x, A.y-B.y);
//}
//bool operator < (const Point& a, const Point& b){// if(a.x == b.x)
// return a.y < b.y;
// return a.x < b.x;
//}
//int Cross(Vector v0, Vector v1) {// return v0.x*v1.y - v1.x*v0.y;
//}//计算凸包,输入点数组为 p,个数为 n, 输出点数组为 ch。函数返回凸包顶点数
//如果不希望凸包的边上有输入点,则把两个 <= 改为 <
//在精度要求高时建议用dcmp比较
//输入不能有重复点,函数执行完后输入点的顺序被破坏
//Point lst[maxn];
//Point stk[maxn], top;
//int ConvexHull(int n) {// sort(lst, lst+n);
// int m = 0;
// for(int i = 0; i < n; ++i) {// while(m > 1 && Cross(stk[m-1] - stk[m-2], lst[i] - stk[m-2]) < 0) {// m--;
// }
// stk[m++] = lst[i];
// }
// int k = m;
// for(int i = n-2; i>= 0; --i) {// while(m > k && Cross(stk[m-1] - stk[m-2], lst[i] - stk[m-2]) < 0) {// m--;
// }
// stk[m++] = lst[i];
// }
// if(n > 1)
// --m;
// return m;
//}signed main()
{int x,y;int k = 0;while(~scanf("%d,%d,",&x,&y)){lst[k++] = {x,y};}bool f = 1;if(k<3) f = 0;else{for(int i=0;i<k;i++){if(!f) break;for(int j=i+1;j<k;j++){if(!f) break;for(int p=j+1;p<k;p++){if(Cross(lst[i]-lst[j],lst[i]-lst[p])==0){f = 0;break;}} } } if(f){Graham(k);if(k!=top) f = 0;}} if(f){int id = -1;int mi = 10000000.00; //距离的平方. Point w;w.x = 0,w.y = 0;for(int i=0;i<k;i++){if(Dis(lst[i],w)<mi){id = i;mi = Dis(lst[i],w);}}printf("%d,%d,",lst[id].x,lst[id].y);int o = 1;// 按照一个方向输出 (逆时针)for(int i=k-1;i>id;i--){o++;if(o!=k) printf("%d,%d,",lst[i].x,lst[i].y);else printf("%d,%d",lst[i].x,lst[i].y);} for(int i=id-1;i>=0;i--){o++;if(o!=k) printf("%d,%d,",lst[i].x,lst[i].y);else printf("%d,%d",lst[i].x,lst[i].y);}}else{printf("ERROR");} return 0;
}
// 0,0,2,0,1,1,1,2
//(P[i].x==P[j].x && P[j].x==P[p].x) || (fabs(((double)P[p].y-P[j].y)/((double)P[p].x-P[j].x))-fabs(((double)P[i].y-P[j].y)/((double)P[i].x-P[j].x))<=1e-2)
八、G Longest Prefix Matching
字典树.
这两天有时间接着做吧…
The 2021 ICPC Asia Regionals Online Contest (I)相关推荐
- 2021 ICPC Asia Regionals Online Contest (II) Problem G. Limit
The 2021 ICPC Asia Regionals Online Contest (II) Problem G. Limit 在欧教的指导下,复习了下高数知识,写下了这题的题解- 做这道题之前, ...
- 【ICPC 2021网络赛2】The 2021 ICPC Asia Regionals Online Contest (II)签到题5题
M. Addition 题意: 给出n,接下来三行,每行n位二进制数,分别表示符号sgn{-1,1}和a{0,1}, b{0,1}. 令c=a+b(a和sgn每位相乘得到数a),最后将c拆成每一位输出 ...
- 2021ICPC网络赛第二场The 2021 ICPC Asia Regionals Online Contest (II) 【L Euler Function】
分析: 根据欧拉函数的那个性质 if(p是质数){if(i % p == 0) f[i * p] = f[i] * p;else f[i * p] = f[i] * (p - 1);} 每次区间乘的那 ...
- The 2021 ICPC Asia Regionals Online Contest (II)
比赛链接 A. Sort 暴力 k=1k=1k=1 检查数组是否有序: k=2k=2k=2 相当于再环上找个起点使得数组有序,直接判断: k≥3k\ge 3k≥3 考虑插入排序,每次暴力找到第 iii ...
- The 2022 ICPC Asia Regionals Online Contest (I)
D题 The 2022 ICPC Asia Regionals Online Contest (I) 03:14:13 H Step Debugging 作者 pku 单位 北京大学 Rikka is ...
- 【题目记录】——The 2021 ICPC Asia Jinan Regional Contest
文章目录 C Optimal Strategy 组合数 H Game Coin K Search For Mafuyu 欧拉序列 题目集地址 The 2021 ICPC Asia Jinan Regi ...
- The 2022 ICPC Asia Regionals Online Contest (II) A、B、E、F、G、J、L
文章目录 A-Yet Another Remainder 题目 题解 B-Non-decreasing Array 题目 题解 E-An Interesting Sequence 题目 题解 F-In ...
- The 2022 ICPC Asia Regionals Online Contest (II) 2022ICPC第二场网络赛 ABEFGJKL题解
文章目录 A Yet Another Remainder[费马小定理] B Non-decreasing Array[线性DP] E An Interesting Sequence[签到] F Inf ...
- The 2022 ICPC Asia Regionals Online Contest (II) J
J:A Game about Increasing Sequences 不是特别会博弈,只能说一下大概意思 Alice and Bob like playing games. The game is ...
最新文章
- 阿里“火拼”拼多多,要“1元”抢占下沉市场
- 【深度学习入门到精通系列】拿捏Dice系数
- 【Android】Android 设置Activity窗体 不显示标题和全屏显示
- LeetCode Super Pow(快速求幂算法)
- poj 3207 Ikki's Story IV - Panda's Trick(2-SAT)
- device eth0 does not seem to be present, delaying initialization
- pytorch 使用cpu_想读读PyTorch底层代码?这份内核机制简介送给你
- Linux项目日报,1Password推出Linux版本 现已进入公开预览阶段
- pom.xml中依赖的optionaltrue/optional标签
- Java-虚拟机-常量池的表现方式
- 深入理解 WordPress 数据库中的用户数据 wp_user
- 关于iOS声音识别的框架
- 47 Majority Element II
- 超级外链工具_慈溪SEO优化_豆瓣外链:豆瓣小组做外链的注意事项?
- 【算法】非线性动力学混沌、分岔图、最大李雅普诺夫指数等
- 阿波罗apollo使用方法+领英使用
- 详解HTTP协议(二)
- 金蝶 EAS WebService 发布过程
- 中秋之夜——随笔杂谈
- win11设置合盖不采取任何操作后,仍无法避免合盖休眠的解决方案
热门文章
- mysql的安装与卸载
- 批量ping IP并检测IP延迟率和丢包率脚本
- 时间对象与字符串对象之间相互转换
- http://blog.seirsoft.com
- 利用XML实现通用WEB报表打印(参考)
- Unity C#笔记 委托事件
- 【leetcode】91. Decode Ways A-Z的字母表示1-26的数字,反向破解多少种字符串的可能性...
- MyEclipse代码提示快捷键和常用设置
- android ListView 九大重要属性详细分析
- 增强SEO的div+css命名规则