T1
美丽的序列
dp 中记录每个数上一次出现位置和当前位置的差,和 \(7\)(或这个数)取 \(\min\)。状态数很少,直接做即可。
代码
#include <iostream>
#include <unordered_map>
#include <vector>
#include <map>
using namespace std;
const int P = 1000000007;
inline void Madd(int& x, int y) { (x += y) >= P ? (x -= P) : 0; }
int n, m;
int a[10];
bool u[10];
unordered_map<int, int> mp;
int _mp[310005];
int cnt;
int out[310005][12];
int pw[12];
void dfs(int x, int cur) {
if (x == m + 1) {
if (!u[0])
return;
if (!mp.count(cur))
_mp[mp[cur] = ++cnt] = cur;
return;
}
for (int i = 0; i < 7; i++) {
if (!u[i]) {
u[i] = 1;
dfs(x + 1, cur + i * pw[x - 1]);
u[i] = 0;
}
}
dfs(x + 1, cur + 7 * pw[x - 1]);
}
int dp[105][310005];
int main() {
freopen("seq.in", "r", stdin);
freopen("seq.out", "w", stdout);
pw[0] = 1;
for (int i = 1; i <= 9; i++) pw[i] = pw[i - 1] * 10;
cin >> n >> m;
for (int i = 1; i <= m; i++) cin >> a[i];
dfs(1, 0);
int ecnt = 0;
for (int i = 1; i <= cnt; i++) {
int tmp = _mp[i];
for (int j = 0; j < m; j++) {
if ((_mp[i] % pw[j + 1]) / pw[j] != 7)
tmp += pw[j];
}
for (int j = 1; j <= m; j++) {
int t = (_mp[i] % pw[j]) / pw[j - 1];
if (t >= a[j] - 1) {
t = (tmp % pw[j]) / pw[j - 1];
out[i][j] = mp[tmp - t * pw[j - 1]];
}
}
}
for (int i = 1; i <= m; i++) {
int x = 0;
for (int j = 1; j <= m; j++)
x = x + 7 * (i != j) * pw[j - 1];
dp[1][mp[x]] = 1;
}
int ans = 0;
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= cnt; j++) {
if (!dp[i - 1][j])
continue;
for (int k = 1; k <= m; k++)
(out[j][k]) ? Madd(dp[i][out[j][k]], dp[i - 1][j]) : void();
}
}
for (int i = 1; i <= cnt; i++) Madd(ans, dp[n][i]);
cout << ans << "\n";
return 0;
}
T2
一
开一棵线段树维护原序列,每次操作相当于合并左右儿子或交换左右儿子。只考虑把右儿子并到左儿子的操作,则另一种操作可以通过再交换左右儿子实现。考虑对每一层打标记,注意到如果发生了合并操作,则这次合并之前的操作都是没用的,所以只需要关心最后一次合并操作以及其之后的交换操作。由于每层的每个点操作的进度不一样,考虑在每一层记一个时间轴。对每个点记录其当前执行到了哪一个合并操作,然后 pushdown 一个点的时候就检查它是否还有没执行的合并操作,然后再看是否要交换左右儿子。合并都是线段树合并,容易发现复杂度是对的。
代码
#include <iostream>
#define int long long
#define lowbit(x) ((x) & (-(x)))
using namespace std;
int n, q;
int a[600005];
struct node {
int l, r, s;
int tg;
} T[50000005];
int lm[30], t[30]; // last merge, cur time
struct Segment_Tree {
int ncnt;
int New(int d) { T[++ncnt] = (node) { 0, 0, 0, t[d] }; return ncnt; }
void pushdown(int o, int d) {
if (T[o].tg < lm[d])
T[o].l = Merge(T[o].l, T[o].r, d - 1), T[o].r = 0, T[o].tg = lm[d];
if ((t[d] ^ T[o].tg) & 1)
swap(T[o].l, T[o].r);
T[o].tg = t[d];
}
int Merge(int x, int y, int d) {
if (!x || !y)
return x | y;
if (!d) {
T[x].s += T[y].s;
return x;
}
pushdown(x, d);
pushdown(y, d);
T[x].l = Merge(T[x].l, T[y].l, d - 1);
T[x].r = Merge(T[x].r, T[y].r, d - 1);
T[x].s = T[T[x].l].s + T[T[x].r].s;
return x;
}
void Add(int& o, int l, int r, int x, int y, int d) {
if (!o)
o = New(d);
if (l == r) {
T[o].s += y;
return;
}
pushdown(o, d);
int mid = (l + r) >> 1;
x <= mid ? Add(T[o].l, l, mid, x, y, d - 1) : Add(T[o].r, mid + 1, r, x, y, d - 1);
T[o].s = T[T[o].l].s + T[T[o].r].s;
}
int Query(int o, int l, int r, int L, int R, int d) {
if (!o)
return 0;
if (L <= l && r <= R)
return T[o].s;
pushdown(o, d);
int mid = (l + r) >> 1;
if (R <= mid)
return Query(T[o].l, l, mid, L, R, d - 1);
if (L > mid)
return Query(T[o].r, mid + 1, r, L, R, d - 1);
return Query(T[o].l, l, mid, L, R, d - 1) + Query(T[o].r, mid + 1, r, L, R, d - 1);
}
} seg;
int rt;
signed main() {
freopen("jeden.in", "r", stdin);
freopen("jeden.out", "w", stdout);
cin >> n >> q;
int d = -1;
for (int x = n; x; x /= 2) ++d;
// cout << __lg(n) << "\n";
for (int i = 0; i < n; i++) cin >> a[i], seg.Add(rt, 0, n - 1, i, a[i], d);
while (q--) {
string s;
int x, y;
cin >> s >> x;
if (s == "add") {
cin >> y;
seg.Add(rt, 0, n - 1, x, y, d);
} else if (s == "sum") {
cin >> y;
cout << seg.Query(rt, 0, n - 1, x, y, d) << "\n";
} else if (s == "and") {
for (int i = 1; i <= d; i++) {
if (!(x & (1 << (i - 1))))
lm[i] = ++t[i];
}
} else if (s == "or") {
for (int i = 1; i <= d; i++) {
if (x & (1 << (i - 1)))
lm[i] = ++t[i], ++t[i];
}
} else
for (int i = 1; i <= d; i++) t[i] += (x >> (i - 1)) & 1;
}
return 0;
}
T3
朋友
首先每条鱼的行动范围是一段区间。然后会发现在钦定了最大的聚集位置之后,其两边都不会互相产生任何影响,也就是两边独立。因此直接考虑区间 dp,转移枚举当前区间中最大的聚集地,然后令这个区间中所有能走到这个聚集地的都走到这个聚集地,算一下贡献即可。
代码
#include <iostream>
#include <algorithm>
#define int long long
using namespace std;
int n, m, w;
int h[10005];
int p[205], J[205];
int mx[17][10005];
int lg2[10005];
int L[10005], R[10005];
int d[405], dcnt;
inline int Qmax(int l, int r) {
int k = lg2[r - l + 1];
return max(mx[k][l], mx[k][r - (1 << k) + 1]);
}
int S[405][405][405];
int dp[405][405];
inline int C2(int x) { return x * (x - 1) / 2; }
signed main() {
freopen("friend.in", "r", stdin);
freopen("friend.out", "w", stdout);
cin >> n >> m >> w;
lg2[0] = -1;
for (int i = 1; i <= n; i++) cin >> h[i], h[i] = w - h[i], mx[0][i] = h[i], lg2[i] = lg2[i - 1] + ((i & (i - 1)) == 0);
for (int i = 1; (1 << i) <= n; i++) {
for (int j = 1; j + (1 << i) - 1 <= n; j++)
mx[i][j] = max(mx[i - 1][j], mx[i - 1][j + (1 << (i - 1))]);
}
for (int i = 1; i <= m; i++) {
cin >> p[i] >> J[i];
int l = 1, r = p[i], mid;
L[i] = p[i] + 1;
R[i] = p[i] - 1;
while (l <= r) {
mid = (l + r) >> 1;
if (Qmax(mid, p[i]) < J[i])
L[i] = mid, r = mid - 1;
else
l = mid + 1;
}
l = p[i], r = n;
while (l <= r) {
mid = (l + r) >> 1;
if (Qmax(p[i], mid) < J[i])
R[i] = mid, l = mid + 1;
else
r = mid - 1;
}
L[i] = max(1ll, L[i] - 1);
R[i] = min(n, R[i] + 1);
d[++dcnt] = L[i];
d[++dcnt] = R[i];
}
sort(d + 1, d + dcnt + 1);
dcnt = unique(d + 1, d + dcnt + 1) - d - 1;
for (int i = 1; i <= m; i++) {
L[i] = lower_bound(d + 1, d + dcnt + 1, L[i]) - d;
R[i] = lower_bound(d + 1, d + dcnt + 1, R[i]) - d;
}
for (int i = 1; i <= dcnt; i++) {
for (int j = 1; j <= m; j++) {
if (L[j] <= i && i <= R[j])
++S[i][L[j]][R[j]];
}
for (int j = dcnt; j; j--) {
for (int k = 1; k <= dcnt; k++)
S[i][j][k] += S[i][j + 1][k] + S[i][j][k - 1] - S[i][j + 1][k - 1];
}
}
for (int i = 1; i <= dcnt; i++) dp[i][i] = C2(S[i][i][i]);
for (int i = 2; i <= dcnt; i++) {
for (int l = 1; l + i - 1 <= dcnt; l++) {
int r = l + i - 1;
for (int k = l; k <= r; k++) dp[l][r] = max(dp[l][r], dp[l][k - 1] + dp[k + 1][r] + C2(S[k][l][r]));
}
}
cout << dp[1][dcnt] << "\n";
return 0;
}
T4
环覆盖
咕咕咕。
标签:return,pw,int,mid,20241101,include,cur From: https://www.cnblogs.com/forgotmyhandle/p/18521696