G. Function Query
题意
给你一个数组 
input
5 6
3 5 1 2 4
0 2
1 1
2 3
3 2
4 2
5 8
output
2
3
2
1
4
-1
我们发现对于给定的 
我们发现如果不存在 
下标肯定不是盲目去找的,要想到找到某些具有特殊性质的下标。由于异或并不满足单调性,那么我们的特殊性质就很少了。我们应该想到需要找下标最小的点(最大也可以,下面以最小为例子),这样如果找到了满足
那么我们怎么去找呢?看到二进制,我们可以想到逐位比较。用字典树记录
code
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define X first
#define Y second
#define umap unordered_map
using ll = long long;
using ull = unsigned long long;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int maxn = 2e5 + 5, mod = 1e9 + 7, maxp = 31, inf = 1e9;
const ll INF = 1e18;
const double eps = 1e-6;
struct Trie {
    vector<vector<int>> ch;
    vector<int> z;
    Trie(int n) {
        ch.resize((n + 1) << 4);
        z.resize((n + 1) << 4);
        for (int i = 0; i < ((n + 1) << 4); i++) {
            ch[i].resize(2);
        }
    }
    int idx = 0;
    void insert(int x, int id) {
        int p = 0;
        for (int j = 31; j >= 0; j--) {
            int k = x >> j & 1;
            if (!ch[p][k]) {
                ch[p][k] = ++idx;
                z[idx] = id;
            }
            p = ch[p][k];
        }
    }
    int querym(int a, int b) {
        int ans = -1;
        int p = 0;
        for (int j = 31; j >= 0; j--) {
            bool f = false, g = false;
            if (a >> j & 1) {
                f = true;
            }
            if (b >> j & 1) {
                g = true;
            }
            if (f && g) {
                if (ch[p][1]) {
                    int res = z[ch[p][1]];
                    if (ans == -1) {
                        ans = res;
                    }
                    else {
                        ans = min(ans, res);
                    }
                }
                if (!ch[p][0]) {
                    return ans;
                }
                p = ch[p][0];
            }
            if (f && !g) {
                if (!ch[p][1]) {
                    return ans;
                }
                p = ch[p][1];
            }
            if (!f && g) {
                if (ch[p][0]) {
                    int res = z[ch[p][0]];
                    if (ans == -1) {
                        ans = res;
                    }
                    else {
                        ans = min(ans, res);
                    }
                }
                if (!ch[p][1]) {
                    return ans;
                }
                p = ch[p][1];
            }
            if (!f && !g) {
                if (!ch[p][0]) {
                    return ans;
                }
                p = ch[p][0];
            }
        }
        return ans;
    }
    int queryb(int a, int b) {
        int ans = -1;
        int p = 0;
        for (int j = 31; j >= 0; j--) {
            bool f = false, g = false;
            if (a >> j & 1) {
                f = true;
            }
            if (b >> j & 1) {
                g = true;
            }
            if (f && g) {
                if (!ch[p][0]) {
                    return ans;
                }
                p = ch[p][0];
            }
            if (f && !g) {
                if (ch[p][0]) {
                    int res = z[ch[p][0]];
                    if (ans == -1) {
                        ans = res;
                    }
                    else {
                        ans = min(ans, res);
                    }
                }
                if (!ch[p][1]) {
                    return ans;
                }
                p = ch[p][1];
            }
            if (!f && g) {
                if (!ch[p][1]) {
                    return ans;
                }
                p = ch[p][1];
            }
            if (!f && !g) {
                if (ch[p][1]) {
                    int res = z[ch[p][1]];
                    if (ans == -1) {
                        ans = res;
                    }
                    else {
                        ans = min(ans, res);
                    }
                }
                if (!ch[p][0]) {
                    return ans;
                }
                p = ch[p][0];
            }
        }
        return ans;
    }
};
void solve() {
    int n, q;
    cin >> n >> q;
    Trie tree(n + 1);
    map<int, int> mp;
    for (int i = 1; i <= n; i++) {
        int x;
        cin >> x;
        tree.insert(x, i);
        mp[x] = min(i, n - 1);
    }
    while (q--) {
        int a, b;
        cin >> a >> b;
        if (mp.contains(a ^ b)) {
            cout << mp[a ^ b] << endl;
            continue;
        }
        int ans = max(tree.queryb(a, b), tree.querym(a, b));
        if (ans <= 1) {
            ans = -1;
        }
        else {
            ans--;
        }
        cout << ans << endl;
    }
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int tt = 1;
    // cin >> tt;
    while (tt--) solve();
    return 0;
}
A. Reverse Pairs Coloring
题意
给你一个长度为
input
9
5 9 1 8 2 6 4 7 3
output
5
可以对小数据画图分析。 比如题目所给样例,最后的方格是这样的:
xxxx.....
xxxx.xxx.
.........
.xxx.xx..
.........
..xx.....
..x......
..x......
.........
我们发现以下性质:
1. 对于第 
2. 对于每个
于是我们可以模拟以下过程:
1. 对于每一个 
2. 对于每一个 
这样我们就模拟完了这个过程。但是目前还有一点问题,那就是怎么去记录每一行的染色情况呢?我们可以转换一下过程:只有一行。首先所有方格都染色。遍历到第
所以现在我们只需要维护一个数组了。由于是取前 
code
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define X first
#define Y second
#define umap unordered_map
using ll = long long;
using ull = unsigned long long;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int maxn = 2e5 + 5, mod = 1e9 + 7, maxp = 31, inf = 1e9;
const ll INF = 1e18;
const double eps = 1e-6;
template<class T>
struct BIT {
    vector<T> c;
    int ub;
    BIT() {}
    BIT(int ub_) {
        ub = ub_;
        init();
    }
    void init() {
        c.resize(ub + 1);
        c.assign(ub + 1, 0);
    }
    int lowbit(int x) {
        return x & -x;
    }
    void add(int pos, T val) {
        if (pos <= 0) return;
        while (pos <= ub) {
            c[pos] += val;
            pos += lowbit(pos);
        }
    }
    T query(int pos) {
        if (pos <= 0) return 0;
        T res = 0;
        while (pos) {
            res += c[pos];
            pos -= lowbit(pos);
        }
        return res;
    }
    T query(int l, int r) {
        return query(r) - query(l - 1); 
    }
};
void solve() {
    int n;
    cin >> n;
    vector<int> a(n + 1);
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    vector<bool> vis(n + 2, true);
    vis[0] = vis[n + 1] = false;
    BIT<int> c(n);
    c.add(1, 1);
    ll ans = 0;
    for (int i = 1; i <= n; i++) {
        int x = a[i];
        vis[x] = false;
        if (c.query(x, x)) {
            c.add(x, -1);
        }
        if (vis[x + 1]) {
            c.add(x + 1, 1);
        }
        if (a[i] < a[i - 1]) continue;
        ans += c.query(a[i - 1], a[i]);
    }
    cout << ans << endl;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int tt = 1;
    // cin >> tt;
    while (tt--) solve();
    return 0;
}