Codeforces #356C: Knight Tournament 题解
来源:互联网 发布:试述数据库设计的步骤 编辑:程序博客网 时间:2024/05/15 12:49
这题看到后我的第一想法是用set
开一个set存储当前还存活的人
每次给一个l和r后,在set里lower_bound一下,然后除了胜利者的人都erase掉
因为每个元素进set一次,出set一次,所以是O(nlogn)的
#include <cstdio>#include <iostream>#include <cstring>#include <string>#include <cmath>#include <algorithm>#include <cstdlib>#include <utility>#include <map>#include <stack>#include <set>#include <vector>#include <queue>#include <deque>#define x first#define y second#define mp make_pair#define pb push_back#define LL long long#define Pair pair<int,int>#define LOWBIT(x) x & (-x)using namespace std;const int MOD=1e9+7;const int INF=0x7ffffff;const int magic=348;int n,m;set<int> s;set<int>::iterator lit,rit,iter;int ans[300048];int dd[300048],top=0;void init(){int i;for (i=1;i<=n;i++) s.insert(i);}int main (){int i,j,l,r,winner;scanf("%d%d",&n,&m);init();for (i=1;i<=m;i++){scanf("%d%d%d",&l,&r,&winner);lit=s.lower_bound(l);rit=s.lower_bound(r);if (*rit==r) rit++;top=0;for (iter=lit;iter!=rit;iter++)if (*iter!=winner){ans[*iter]=winner;dd[++top]=*iter;}for (j=1;j<=top;j++) s.erase(dd[j]);}for (i=1;i<=n;i++) printf("%d ",ans[i]);return 0;}
后来想到一种更好的用dsu的算法
暴力的解法是O(n*n),瓶颈在于已经被删除的元素被重复考虑
所以我们可以用dsu来跳过那些已经被删除的元素
如果一个选手x已经被打败,那么就合并x和x+1
这样在循环的时候不断的找anc,每个元素仅被找到一次,O(n)
#include <cstdio>#include <iostream>#include <cstring>#include <string>#include <cmath>#include <algorithm>#include <cstdlib>#include <utility>#include <map>#include <stack>#include <set>#include <vector>#include <queue>#include <deque>#define x first#define y second#define mp make_pair#define pb push_back#define LL long long#define Pair pair<int,int>#define LOWBIT(x) x & (-x)using namespace std;const int MOD=1e9+7;const int INF=0x7ffffff;const int magic=348;int ans[300048]; int pre[300048];int find_anc(int x){if (pre[x]!=x) pre[x]=find_anc(pre[x]);return pre[x];}void update(int x,int y){x=find_anc(x);y=find_anc(y);pre[x]=y;}int n,m;int main (){int i,j,l,r,winner;scanf("%d%d",&n,&m);for (i=1;i<=n+1;i++) pre[i]=i;for (i=1;i<=m;i++){scanf("%d%d%d",&l,&r,&winner);for (j=find_anc(l);j<=r;j=find_anc(j)){if (j!=winner){ans[j]=winner;update(j,j+1);}elsej++;}for (i=1;i<=n;i++) printf("%d ",ans[i]);return 0;}
阅读全文
0 0
- Codeforces #356C: Knight Tournament 题解
- codeforces 357C Knight Tournament
- CodeForces 357C - Knight Tournament(模拟)
- CodeForces 356A Knight Tournament 【线段树】
- Knight Tournament CodeForces
- Codeforces Round #207 (Div. 2) C. Knight Tournament
- Codeforces Round #207 (Div. 2) C. Knight Tournament
- Codeforces Round #207 (Div. 2) C. Knight Tournament
- Codeforces Round #207 (Div. 2) C. Knight Tournament (并查集缩点)
- Codeforces Round #207 (Div. 2)---C. Knight Tournament(set乱搞)
- Codeforces Round #207 (Div. 2) C - Knight Tournament
- Codeforces 357C Knight Tournament【并查集】
- 356A - Knight Tournament
- CodeForces 356A - Knight Tournament set or 线段树
- Codeforces 356A Knight Tournament线段树区间覆盖
- CodeForces - 357C C - Knight Tournament 并查集or set模拟
- [Codeforces 878C] Tournament
- Codeforces Round #207 (Div. 2)C. Knight Tournament(SET也可以搞定)
- switch-case选择结构
- win10+python3.5+pycharm5.0+CPU 安装tensorflow
- NGUI学习
- 面试总结
- android_有序广播
- Codeforces #356C: Knight Tournament 题解
- 流程结构:顺序,循环,选择
- 密码最短长度为7,其中必须包含以下非字母数字字符1 完美解决方案
- python中range()、xrange()和np.arange()区别
- TCP状态转换图
- Struts2 -工作流程图
- three.js详解
- pycharm下robot framework环境搭建
- I