int solve() {
int a, b, c; cin >> a >> b >> c;
if (a == b) return c;
if (a == c) return b;
return a;
}
char solve() {
int sum = ('A' + 'B' + 'C') * 3 + '?';
for (int i = 0; i < 3; i ++) {
cin >> s[i];
for (int j = 0; j < 3; j ++) sum -= s[i][j];
}
return (char)sum;
}
string solve() {
cin >> n;
ll res = 0;
for (int i = 0; i < n; i ++) {
int x; cin >> x;
res += x;
}
ll x = sqrt(res);
return x * x == res ? yes : no;
}
void solve() {
cin >> n >> s;
for (int i = 0; i < n; i ++) {
cout << s[i];
if (i + 2 < n && (s[i + 2] == 'a' || s[i + 2] == 'e')) cout << '.';
}
cout << endl;
}
int n, m;
int a[N];
ll pre[N];
string solve() {
cin >> n;
for (int i = 1; i <= n; i ++) {
cin >> a[i];
pre[i] = pre[i - 1] + a[i] * pow(-1, i & 1);
}
map<ll, bool> mp;
mp[0] = true;
for (int i = 1; i <= n; i ++) {
if (mp[pre[i]]) return yes;
else mp[pre[i]] = true;
}
return no;
}
可以发现只有下列情况计算一次贡献,即区间包含关系
L[ ]R
l[ ]r
法一:树状数组,每次在 L < l L
int n, m;
int l;
pii a[N];
int b[N];
int tr[N];
inline int lowbit(int x) { return x & -x; }
void update(int x, int k = 1) {
while (x <= l) {
tr[x] += k;
x += lowbit(x);
}
}
int query(int x) {
int res = 0;
while (x) {
res += tr[x];
x -= lowbit(x);
}
return res;
}
ll solve() {
cin >> n;
for (int i = 0; i < n; i ++) {
cin >> a[i].aa >> a[i].bb;
b[i] = a[i].bb;
}
sort(a, a + n);
sort(b, b + n);
l = unique(b, b + n) - b;
for (int i = 0; i <= l; i ++) tr[i] = 0;
ll res = 0;
for (int i = 0; i < n; i ++) {
int x = lower_bound(b, b + n, a[i].bb) - b;
res += query(l - x);
update(l - x);
}
return res;
}
法二:用 vector
的 erase
函数,奇怪的是复杂度为 O ( n 2 ) O(n^2) O(n2),竟然过了
int n, m;
pii a[N];
int b[N];
ll solve() {
cin >> n;
vector<int> b;
for (int i = 0; i < n; i ++) {
cin >> a[i].aa >> a[i].bb;
b.push_back(a[i].bb);
}
sort(a, a + n);
sort(b.begin(), b.end());
ll res = 0;
for (int i = 0; i < n; i ++) {
auto it = lower_bound(b.begin(), b.end(), a[i].bb);
res += it - b.begin();
b.erase(it);
}
return res;
}
法三:排序使得 a i < a j a_i\lt a_j ai<aj,只要统计 b i > a j b_i\gt a_j bi>aj 的数量,归并排序统计逆序对
ai[ ]aj
bi[ ]bj
int n, m;
pii a[N];
int q[N], t[N];
ll res = 0;
void mergeSort(int l, int r) {
if (l == r) return;
int mid = l + r >> 1;
mergeSort(l, mid), mergeSort(mid + 1, r);
int i = l, j = mid + 1, k = 0;
while (i <= mid && j <= r) {
if (q[i] <= q[j]) t[k ++] = q[i ++];
else {
res += mid - i + 1;
t[k ++] = q[j ++];
}
}
while (i <= mid) t[k ++] = q[i ++];
while (j <= r) t[k ++] = q[j ++];
for (int i = l, k = 0; i <= r; i ++, k ++) q[i] = t[k];
}
ll solve() {
cin >> n;
for (int i = 0; i < n; i ++) cin >> a[i].aa >> a[i].bb;
sort(a, a + n);
for (int i = 0; i < n; i ++) q[i] = a[i].bb;
res = 0;
mergeSort(0, n - 1);
return res;
}