Educational Codeforces Round 41(已补D,E)
Posted 啊嘞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Educational Codeforces Round 41(已补D,E)相关的知识,希望对你有一定的参考价值。
D. Pair Of Lines
题目大意:
给\(n\)个点,问是否存在两条直线(可以为同一条)能覆盖所有的点。
解题思路:
首先一个或者两个或者三个点都是肯定可以用两条线覆盖的。
如果点的个数大于等于三个,那么我们已经可以确定至少一条线的:
点1和点2可能在一条线上,点2和点3可能在一条线上,点3和点1可能在一条线上。
我们试着确定其中一条线后,去掉在线上的所有点,剩下的点肯定在另一条线上,这样利用剩下的点就可以确定另一条直线。
用到一个公式:\(abc\)三点共线\((c - a)\times(c - b)=0\)
E. Tufurama
题目大意:
给\(n\)个数的数列\(a\),问有多少对下标\(x,y(x<y)\),使得\(a[x]\geq y,a[y]\geq x\)。
解题思路:
大体思路是先遍历一遍数组,求出\(a[y]\geq x\)中最大的下标\(x\),
然后再遍历一遍数组,用树状数组求出\(a[x]\geq y\)的所有\(x\)。
最大可能下标可以这样求:\(x=max\{a[y],y-1\}\)。
为什么要求最大呢?因为是为了配合树状数组的求和,这样就不会重复。
每次求到的最大下标\(x\)对应的\(y\)可以用vector保存。
因为每个\(y\)只能出现一次,所以时间复杂度为\(O(nlogn)\)
#include <bits/stdc++.h>
#define N 200010
int n, a[N];
struct bit {
static const int maxn = N;
int f[maxn];
inline void init() { std::fill(f, f + maxn, 0); }
bit() { init(); }
inline void add(int pos, int inc) {
for (; pos < maxn; pos += (pos & -pos)) f[pos] += inc;
}
inline int sum(int rg) {
if (rg < 1) return 0;
int ans = 0;
for(; rg; rg -= (rg & -rg)) ans += f[rg];
return ans;
}
inline int sum(int l, int r) {
return sum(r) - sum(l - 1);
}
}mybit;
std::vector<int> mpos[N];
int main() {
while (std::cin >> n) {
for (int i = 0; i <= n; i++) mpos[i].clear();
for (int i = 1; i <= n; i++) {
std::cin >> a[i];
a[i] = a[i] > n ? n : a[i];
mpos[std::min(a[i], i - 1)].push_back(i);
}
mybit.init();
long long ans = 0;
for (int i = 1; i <= n; i++) {
mybit.add(a[i], 1);
for (int x: mpos[i]) ans += mybit.sum(x, n);
}
std::cout << ans << ‘\n‘;
}
return 0;
}
以上是关于Educational Codeforces Round 41(已补D,E)的主要内容,如果未能解决你的问题,请参考以下文章
Educational Codeforces Round 7 A
Educational Codeforces Round 7
Educational Codeforces Round 90
Educational Codeforces Round 33