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)相关推荐

  1. 2021 ICPC Asia Regionals Online Contest (II) Problem G. Limit

    The 2021 ICPC Asia Regionals Online Contest (II) Problem G. Limit 在欧教的指导下,复习了下高数知识,写下了这题的题解- 做这道题之前, ...

  2. 【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拆成每一位输出 ...

  3. 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);} 每次区间乘的那 ...

  4. The 2021 ICPC Asia Regionals Online Contest (II)

    比赛链接 A. Sort 暴力 k=1k=1k=1 检查数组是否有序: k=2k=2k=2 相当于再环上找个起点使得数组有序,直接判断: k≥3k\ge 3k≥3 考虑插入排序,每次暴力找到第 iii ...

  5. 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 ...

  6. 【题目记录】——The 2021 ICPC Asia Jinan Regional Contest

    文章目录 C Optimal Strategy 组合数 H Game Coin K Search For Mafuyu 欧拉序列 题目集地址 The 2021 ICPC Asia Jinan Regi ...

  7. 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 ...

  8. 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 ...

  9. 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. 阿里“火拼”拼多多,要“1元”抢占下沉市场
  2. 【深度学习入门到精通系列】拿捏Dice系数
  3. 【Android】Android 设置Activity窗体 不显示标题和全屏显示
  4. LeetCode Super Pow(快速求幂算法)
  5. poj 3207 Ikki's Story IV - Panda's Trick(2-SAT)
  6. device eth0 does not seem to be present, delaying initialization
  7. pytorch 使用cpu_想读读PyTorch底层代码?这份内核机制简介送给你
  8. Linux项目日报,1Password推出Linux版本 现已进入公开预览阶段
  9. pom.xml中依赖的optionaltrue/optional标签
  10. Java-虚拟机-常量池的表现方式
  11. 深入理解 WordPress 数据库中的用户数据 wp_user
  12. 关于iOS声音识别的框架
  13. 47 Majority Element II
  14. 超级外链工具_慈溪SEO优化_豆瓣外链:豆瓣小组做外链的注意事项?
  15. 【算法】非线性动力学混沌、分岔图、最大李雅普诺夫指数等
  16. 阿波罗apollo使用方法+领英使用
  17. 详解HTTP协议(二)
  18. 金蝶 EAS WebService 发布过程
  19. 中秋之夜——随笔杂谈
  20. win11设置合盖不采取任何操作后,仍无法避免合盖休眠的解决方案

热门文章

  1. mysql的安装与卸载
  2. 批量ping IP并检测IP延迟率和丢包率脚本
  3. 时间对象与字符串对象之间相互转换
  4. http://blog.seirsoft.com
  5. 利用XML实现通用WEB报表打印(参考)
  6. Unity C#笔记 委托事件
  7. 【leetcode】91. Decode Ways A-Z的字母表示1-26的数字,反向破解多少种字符串的可能性...
  8. MyEclipse代码提示快捷键和常用设置
  9. android ListView 九大重要属性详细分析
  10. 增强SEO的div+css命名规则