codeforce gym 101726 problem A. Popularity on Facebook
Nowadays everyone is connected, has a Facebook page, posts photos to Instagram and videos to Youtube, and so on. Even GPS systems now are based on social networks, making everything more fun (and harder to understand, but that's another problem).
Being popular on Facebook is almost a need. A person with less than 700, 800 friends may be considered almost a pariah in this new reality.
Maybe that's why some people tend to exaggerate when telling the number of friends they have. Consider a community with N people and, for each one of them, consider we know the number of friends that person says he or she has on this community. Your task is to determine if in fact it is possible that everyone is telling the truth. Remember someone cannot be his or her own friend, and two people cannot be friends more than once.
On the first line T, the number of test cases.
The first line of each test case has an integer N. The second line has N space-separated integers a1, ..., aN. The i-th person claims to have ai friends on the community.
Limits
- 1 ≤ N ≤ 105
- 0 ≤ ai ≤ 105
- The sum of N over all test cases does not exceed 5·105
For each case, print on a single line Y if it is possible that no one is lying, or N otherwise.
2
3
1 1 1
3
2 2 2
N
Y
思路:将度数最小的连接最大的那x个,于是需要一个区间修改的数据结构。同时你删完一段区间后还要保证整体区间的单调性,而更改后不单调递增的话只可能是前面比后面一段大1,故二分得出两端区间左右端点,再进行两次区间修改就行了。
复杂度nlog2n.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 36 /* 37 #include <ext/pb_ds/assoc_container.hpp> 38 #include <ext/pb_ds/tree_policy.hpp> 39 40 using namespace __gnu_pbds; 41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T; 42 */ 43 44 int n, t, a[100015]; 45 int val[400015], lazy[400015]; 46 void pushdown(int i) { 47 if (lazy[i]) { 48 lazy[i << 1] += lazy[i]; 49 lazy[i << 1 | 1] += lazy[i]; 50 lazy[i] = 0; 51 } 52 } 53 void build(int i, int l, int r) { 54 lazy[i] = 0; 55 if (l == r) { 56 val[i] = a[l]; 57 return; 58 } 59 int mi = l + r >> 1; 60 build(i << 1, l, mi); 61 build(i << 1 | 1, mi + 1, r); 62 } 63 void update(int i, int l, int r, int x, int y, int z) { 64 if (y < x) return; 65 if (x <= l && r <= y) { 66 lazy[i] += z; 67 return; 68 } 69 pushdown(i); 70 int mi = l + r >> 1; 71 if (x <= mi) update(i << 1, l, mi, x, y, z); 72 if (mi < y) update(i << 1 | 1, mi + 1, r, x, y, z); 73 } 74 int query(int i, int l, int r, int x) { 75 if (l == x && x == r) { 76 return val[i] + lazy[i]; 77 } 78 int mi = l + r >> 1; 79 pushdown(i); 80 if (x <= mi) return query(i << 1, l, mi, x); 81 if (mi < x) return query(i << 1 | 1, mi + 1, r, x); 82 } 83 int main() { 84 scanf("%d", &t); 85 while (t--) { 86 scanf("%d", &n); 87 for (int i = 1; i <= n; ++i) { 88 scanf("%d", &a[i]); 89 } 90 sort(a + 1, a + n + 1); 91 build(1, 1, n); 92 int flag = 1; 93 for (int i = 1; i < n; ++i) { 94 int x = query(1, 1, n, i), p1 = n - x + 1; 95 if (!x) continue; 96 if (p1 <= i) { 97 flag = 0; 98 break; 99 } 100 update(1, 1, n, p1, n, -1); 101 int v1 = query(1, 1, n, p1); 102 if (p1 < 0) { 103 flag = 0; 104 break; 105 } 106 int s = i + 1, e = p1 - 1, mi, p2 = p1; 107 while (s <= e) { 108 mi = s + e >> 1; 109 if (v1 < query(1, 1, n, mi)) { 110 e = (p2 = mi) - 1; 111 } else { 112 s = mi + 1; 113 } 114 } 115 s = p1 + 1, e = n; 116 int p3 = p1; 117 while (s <= e) { 118 mi = s + e >> 1; 119 if (v1 == query(1, 1, n, mi)) { 120 s = (p3 = mi) + 1; 121 } else { 122 e = mi - 1; 123 } 124 } 125 int l1 = p1 - p2, l2 = p3 - p1 + 1; 126 if (l1 < l2) { 127 update(1, 1, n, p2, p2 + l1 - 1, -1); 128 update(1, 1, n, p3 - l1 + 1, p3, 1); 129 } else { 130 update(1, 1, n, p2, p2 + l2 - 1, -1); 131 update(1, 1, n, p3 - l2 + 1, p3, 1); 132 } 133 } 134 if (query(1, 1, n, n)) flag = 0; 135 puts(flag ? "Y" : "N"); 136 } 137 return 0; 138 }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步