本篇题解几题参考了AK大佬的题解,)因为本菜太lj了,orz大佬题解真的很漂亮

A、环鸽的CHONG

如果一个数在一段序列中只出现1次,那么我们可以从这个数分隔区间,在左右区间重复寻找是不是有数出现一次即可,递归处理。
这里的寻找遍历是不行的,时间复杂度太爆炸了,考虑散列表。开一个左边和右边上一次出现和下一次的位置。直接跳着找即可。
)这里顺带也问一句为什么用快读就错掉了,如果有大牛发现了,请告诉我一下,万分感谢,我把read函数贴出来,永远TLE,96.55%

#include <bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
using namespace std;
typedef long long ll;

inline ll read() {
    ll s = 0, w = 1; char ch = getchar();
    while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}

const int N = 2e5 + 7;
int a[N], l[N], r[N];
unordered_map<int, int> mp;

int dfs(int L, int R) {
    if (R - L <= 0) return true;
    int x = L, y = R, mid = -1;
    while (x <= y) {
        if (l[x] < L && R < r[x]) { mid = x; break; }
        if (l[y] < L && R < r[y]) { mid = y; break; }
        x++, y--;
    }
    if (mid == -1) return false;
    return dfs(L, mid - 1) && dfs(mid + 1, R);
}

int main() {
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) scanf("%d", a + i);
    for (int i = 1; i <= n; ++i) { //记录当前位置字母的前一次出现位置,没出现为0
        if (!mp[a[i]])  l[i] = 0;
        else l[i] = mp[a[i]];
        mp[a[i]] = i;
    }
    mp.clear();
    for (int i = n; i; --i) {
        if (!mp[a[i]])  r[i] = n + 1;
        else r[i] = mp[a[i]];
        mp[a[i]] = i;
    }
    if (dfs(1, n))  puts("chong");
    else    puts("fuchong");
    return 0;
}

C、环鸽不会X点

后面改的签到题,直接判断最小行不行,如果大于最小再去判断奇偶性即可,奇数+奇数=偶数,只有奇数个奇数才可能是奇数

#include <bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
using namespace std;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
typedef long long ll;
const ll MOD = 1e9 + 7;
inline ll read() { ll s = 0, w = 1; char ch = getchar(); while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();    return s * w; }
inline void write(ll x) { if (!x) { putchar('0'); return; } char F[200]; ll tmp = x > 0 ? x : -x; if (x < 0)putchar('-');    int cnt = 0;    while (tmp > 0) { F[cnt++] = tmp % 10 + '0';        tmp /= 10; }    while (cnt > 0)putchar(F[--cnt]); }
inline ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
ll qpow(ll a, ll b) { ll ans = 1;    while (b) { if (b & 1)    ans *= a;        b >>= 1;        a *= a; }    return ans; }    ll qpow(ll a, ll b, ll mod) { ll ans = 1; while (b) { if (b & 1)(ans *= a) %= mod; b >>= 1; (a *= a) %= mod; }return ans % mod; }
inline int lowbit(int x) { return x & (-x); }

int main() {
    int T = read();
    while (T--) {
        ll n = read(), k = read();
        ll tmp = k * 3;
        if (n < tmp || ((n - k) & 1))    puts("No");
        else puts("Yes");
    }
    return 0;
}

D、小C的棋王之路

刚刚看到大佬的题解,发现是珂朵莉树,混分巨兽,而且是合理的混分!太顶了,这题用珂朵莉就是码码板子就行了,如果你知道函数的作用。
,在还有几个用处我一起放一下把,灵魂就是l,r之间才修改,不然别动它就行了,set去偷鸡!贼快乐,当然如果不被卡!

/*  骗分巨兽珂朵莉树
1区间加数,2区间乘数
3区间赋值,4区间第k小,5区间幂次和
           直接快排    累加即可
*/
#include <bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
using namespace std;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
typedef long long ll;
ll MOD;
inline ll read() { ll s = 0, w = 1; char ch = getchar(); while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();    return s * w; }
inline void write(ll x) { if (!x) { putchar('0'); return; } char F[200]; ll tmp = x > 0 ? x : -x; if (x < 0)putchar('-');    int cnt = 0;    while (tmp > 0) { F[cnt++] = tmp % 10 + '0';        tmp /= 10; }    while (cnt > 0)putchar(F[--cnt]); }
inline ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
ll qpow(ll a, ll b) { ll ans = 1;    while (b) { if (b & 1)    ans *= a;        b >>= 1;        a *= a; }    return ans; }    ll qpow(ll a, ll b, ll mod) { ll ans = 1; while (b) { if (b & 1)(ans *= a) %= mod; b >>= 1; (a *= a) %= mod; }return ans % mod; }
inline int lowbit(int x) { return x & (-x); }

struct Node {
    int l, r;
    mutable ll val;
    Node(int l, int r = -1, ll val = 0) : l(l), r(r), val(val) {}
    bool operator <(const Node& rhs)const {
        return l < rhs.l;
    }
};

set<Node> st;

auto split(int x) { //灵魂!!
    auto it = st.lower_bound(x);
    if (it != st.end() && it->l == x) return it;
    --it;
    int l = it->l, r = it->r;
    ll val = it->val;
    st.erase(it);
    st.insert(Node(l, x - 1, val));
    return st.insert(Node(x, r, val)).first;
}

void add(int l, int r, int x) {
    auto itr = split(r + 1), itl = split(l);
    for (; itl != itr; itl++) itl->val = (itl->val + x) % MOD;
}

void mul(int l, int r, int x) {
    auto itr = split(r + 1), itl = split(l);
    for (; itl != itr; itl++) itl->val = itl->val * x % MOD;
}

void assign(int l, int r, int x) { //赋值
    auto itr = split(r + 1), itl = split(l);
    st.erase(itl, itr);
    st.insert(Node(l, r, x));
}

ll query(int l, int r) {
    ll ans = 0;
    auto itr = split(r + 1), itl = split(l);
    for (; itl != itr; itl++) ans = (ans + itl->val * (itl->r - itl->l + 1) % MOD) % MOD;
    return ans;
}

int main() {
    int n = read(), m = read(); MOD = read();
    for (int i = 1; i <= n; ++i) st.insert(Node(i, i, read()));
    ++n;
    st.insert(Node(n, n, 0)); //哨兵
    while (m--) {
        int op = read(), l, r, x, k;
        if (op <= 3) {
            l = read(), r = read(), k = read();
            if (op == 1)    add(l, r, k);
            else if (op == 2)    mul(l, r, k);
            else    assign(l, r, k);
        }
        else if (op == 4) {
            x = read();
            auto it = st.lower_bound(Node(n));
            st.erase(it); //去掉哨兵
            st.insert(Node(n, n, x));
            ++n;
            st.insert(Node(n, n, 0)); //新加哨兵
        }
        else {
            l = read(), r = read();
            write(query(l, r)), putchar(32);
        }
    }
    return 0;
}