CodeForces - 356A Knight Tournament
http://codeforces.com/problemset/problem/356/A
首先理解题意
每次给出l 和r 在l - r之间还有资格的选手中得出一个胜者
暴力思路:
首先维护还有资格的选手的集合
用一个数组 表示 这个选手被谁击败
每次遍历 l - r 然后把不是胜者 且 还在集合中的选手踢出 并更新这个选手的数组值
最终 输出这个数组即可
这样会TLE
1、 如果用数组维护这个集合的话 每次遍历都是这样就是O(n^2) -->> 所以用set维护这个集合
2、使用set后 如果每次依然从l - r去遍历找在集合中的元素 去find的话 那么就会在 (l, r)的区间两端有浪费的运算 如果每次l, r 都是1 和 n的话 那就浪费得非常得多
所以使用set :: lower_bound() 直接得到第一个大于l 并在集合中的元素 O(logn)
这样优化后 即可
1 #include <iostream> 2 #include <stdio.h> 3 #include <set> 4 using namespace std; 5 6 7 int Par[300007]; 8 int tmp[300007]; 9 set<int> s; 10 11 int find(int x) 12 { 13 if (Par[x] == x) return x; 14 else return find(Par[x]); 15 } 16 17 int main() 18 { 19 int n, m; 20 freopen("in.txt", "r", stdin); 21 scanf("%d%d", &n, &m); 22 for (int i = 0; i <= n; i++) 23 { 24 Par[i] = i; 25 s.insert(i);//加入set中 26 } 27 for(int i = 0; i < m; i++) 28 { 29 int l, r, x; 30 scanf("%d%d%d", &l, &r, &x); 31 set<int> :: iterator pit = s.lower_bound(l);//返回第一个>= l的位置 32 int num = 0; 33 while (pit != s.end() && (*pit) <= r ) 34 { 35 if ((*pit) != x) 36 { 37 Par[*pit] = x; 38 //s.erase(*pit); 不能在这里直接删除 删除后set结构发生改变 pit就失效了 39 tmp[num++] = *pit; 40 } 41 pit++; 42 } 43 for (int j = 0; j < num; j++) s.erase(tmp[j]); 44 } 45 for (int i = 1; i <= n; i++) 46 { 47 if (Par[i] == i) printf("0 "); 48 else printf("%d ", Par[i]); 49 } 50 putchar('\n'); 51 }
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 35岁程序员的中年求职记:四次碰壁后的深度反思
· 继承的思维:从思维模式到架构设计的深度解析
· 如何在 .NET 中 使用 ANTLR4
· 后端思维之高并发处理方案
· 理解Rust引用及其生命周期标识(下)
· 35岁程序员的中年求职记:四次碰壁后的深度反思
· ShadowSql之.net sql拼写神器
· 无需WebView,Vue也能开发跨平台桌面应用
· 使用MCP C# SDK开发MCP Server + Client
· 感觉程序员要被 AI 淘汰了?学什么才有机会?