本篇题解几题参考了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;
}

京公网安备 11010502036488号