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 }
时间: 2024-10-09 23:26:34

CodeForces - 356A Knight Tournament的相关文章

codeforces 357C Knight Tournament(set)

Description Hooray! Berl II, the king of Berland is making a knight tournament. The king has already sent the message to all knights in the kingdom and they in turn agreed to participate in this grand event. As for you, you're just a simple peasant.

Knight Tournament 伪并查集(区间合并)

Knight Tournament Hooray! Berl II, the king of Berland is making a knight tournament. The king has already sent the message to all knights in the kingdom and they in turn agreed to participate in this grand event. As for you, you're just a simple pea

D - Knight Tournament

Problem description Hooray! Berl II, the king of Berland is making a knight tournament. The king has already sent the message to all knights in the kingdom and they in turn agreed to participate in this grand event. As for you, you're just a simple p

Codeforces Round #207 (Div. 1) A. Knight Tournament (线段树离线)

题目:http://codeforces.com/problemset/problem/356/A 题意:首先给你n,m,代表有n个人还有m次描述,下面m行,每行l,r,x,代表l到r这个区间都被x所击败了(l<=x<=r),被击败的人立马退出游戏让你最后输出每个人是被谁击败的,最后那个胜利者没被 人击败就输出0 思路:他的每次修改的是一个区间的被击败的人,他而且只会记录第一次那个被击败的人,用线段树堕落标记的话他会记录最后一次的,所以我们倒着来修改, 然后因为那个区间里面还包含了自己,在线段

区间跳跃问题

区间跳跃问题 有时我们会碰到需要跳着区间处理的问题,这个时候目前我接触到的有两种思路: 一是利用\(set\)来处理,因为\(set\)可以从序列中删除元素,利用好一个或者多个\(set\),就可以完美地解决问题. 二是利用并查集来处理,如何实现跳点呢,看跳的方向是单向还是双向,决定建立几个并查集,维护即可. 下面拿两个例题来解释一下. CF 356A Knight Tournament 这个题大意就是有\(n\)个骑士,每次给出一个区间和一个\(x\),区间内的所有骑士如何还没有被打败,就会被

Codeforces 678E:Another Sith Tournament 状压DP

odd-even number 题目链接: http://codeforces.com/problemset/problem/678/E 题意: 有n个人打擂台赛,每两个人间都有相对的胜率,主角可以操控比赛顺序,求主角最后获胜的最大概率. 题解: 设dp[i][j]为状态 i (二进制位代表出场选手) j 号选手第一个上场时主角的最大胜率,dp[1][0]=1.0(场上只有主角一个人主角必胜). 状态转移方程dp[i][j]=max(dp[i][j],dp[i^(1<<j)][k]*p[k][

【CodeForces】913 F. Strongly Connected Tournament

[题目]F. Strongly Connected Tournament [题意]给定n个点(游戏者),每轮游戏进行下列操作: 1.对于游戏者i和j(i<j),有p的概率i赢j(反之j赢i),连边从赢者向输者,从而得到一个有向完全图,这些点视为进行了一轮游戏. 2.对于其中点数>1的强连通分量再次进行过程1,直至不存在点数>1的强连通分量为止. 给定n和p,求所有点进行的游戏轮数之和,2<=n<=2000. [算法]数学概率,期望DP [题解]参考:官方题解Hello 201

CodeForces - 283E Cow Tennis Tournament

Discription Farmer John is hosting a tennis tournament with his n cows. Each cow has a skill level si, and no two cows having the same skill level. Every cow plays every other cow exactly once in the tournament, and each cow beats every cow with skil

Codeforces 283E Cow Tennis Tournament 线段树 (看题解)

Cow Tennis Tournament 感觉这题的难点在于想到求违反条件的三元组.. 为什么在自己想的时候没有想到求反面呢!!!! 违反的三元组肯定存在一个人能打败其他两个人, 扫描的过程中用线段树维护一下就好了. 反思: 计数问题: 正难则反 正难则反 正难则反 !!!! #include<bits/stdc++.h> #define LL long long #define LD long double #define ull unsigned long long #define fi