2025牛客寒假算法基础集训营4 题解

news/2025/2/8 1:51:46/文章来源:https://www.cnblogs.com/advisedy/p/18703561

Preface

又来了,后面两场要缺席了,旅游去了。依旧是从大概2个小时才开始打的。

我会在代码一些有必要的地方加上注释,签到题可能一般就不会写了.

以下是代码火车头:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <map>
#include <unordered_map>
#include <iomanip>
#define endl '\n'
#define int long long
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define rep2(i,a,b) for(int i=(a);i>=(b);i--)
using namespace std;template<typename T>
void cc(const vector<T> &tem) {for (const auto &x: tem) cout << x << ' ';cout << endl;
}template<typename T>
void cc(const T &a) { cout << a << endl; }template<typename T1, typename T2>
void cc(const T1 &a, const T2 &b) { cout << a << ' ' << b << endl; }template<typename T1, typename T2, typename T3>
void cc(const T1 &a, const T2 &b, const T3 &c) { cout << a << ' ' << b << ' ' << c << endl; }void cc(const string &s) { cout << s << endl; }void fileRead() {
#ifdef LOCALLfreopen("D:\\AADVISE\\Clioncode\\untitled2\\in.txt", "r", stdin);freopen("D:\\AADVISE\\Clioncode\\untitled2\\out.txt", "w", stdout);
#endif
}void kuaidu() { ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); }inline int max(int a, int b) {if (a < b) return b;return a;
}inline double max(double a, double b) {if (a < b) return b;return a;
}inline int min(int a, int b) {if (a < b) return a;return b;
}inline double min(double a, double b) {if (a < b) return a;return b;
}void cmax(int &a, const int &b) { if (b > a) a = b; }
void cmin(int &a, const int &b) { if (b < a) a = b; }
void cmin(double &a, const double &b) { if (b < a) a = b; }
void cmax(double &a, const double &b) { if (b > a) a = b; }
using PII = pair<int, int>;
using i128 = __int128;
using vec_int = std::vector<int>;
using vec_char = std::vector<char>;
using vec_double = std::vector<double>;
using vec_int2 = std::vector<std::vector<int> >;
using que_int = std::queue<int>;

Problem A. Tokitsukaze and Absolute Expectation

首先我们先考虑一下比较简单的情况,如果只有两个数字,区间已知,我们该如何计算?

在这个比较简单的情况我们再继续思考,如果这两个区间是不相交的,我们该如何计算?如果这两个区间是相交的我们又该如何计算?

可以来说一下,如果两个区间是不相交的,对于只考虑两个数。我们该如何计算?其实我们用暴力的方法把每一项都写下来之后,然后再合并,我们可以读不出来。我们把比较小的那个区间称作是区间A,大的那个区间称作是区间B。设sum是一个区间的所有的数字之和,len这个区间的长度大小。

那么他们的贡献就是\(sum_B*len_A-sum_A*len_B\)

那么相交的区间我们应该怎么考虑呢?其实也很简单,我们只需要把每一块儿区间开开来计算两两组合枚举推算就可以了。比如区间a和区间b是相交的,从左到右设立区间Q,W,E。那么我们只需要计算QW,QE,WW,WE的答案就好了。

这是只看两个数的情况,对于有很多的数字,我们只需要从左到右来处理就好啦。就像每一次把当前的数字看做是一个集合,左边我们遍历过的数字是一个集合,而现在是要去合并他们。

用v代表一个集合里的发生的差值之和,c代表集合里的区间大小的乘积。

			v1 = v1 * c2 % mod + v2 * c1 % mod;v1 %= mod;c1 *= (A[i - 1].second - A[i - 1].first + 1);c1 %= mod;

转移方程长这个样子

//--------------------------------------------------------------------------------
const int N = 2e5 + 10;
const int M = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 1e16;
int n, m, T;//--------------------------------------------------------------------------------
//struct or namespace://--------------------------------------------------------------------------------int dfs(int l1,int r1,int l2,int r2) {if (l1 > r1 or l2 > r2) return 0;if (l1 > l2) {swap(l1, l2);swap(r1, r2);}else {if (l1 == l2) {if (r1 > r2) {swap(l1, l2);swap(r1, r2);}}}int ans = 0;auto kuai = Kuai<mod>;if (l1 == l2 and r1 == r2) {int len = r1 - l1 + 1;len -= 1;int v1 = len * (len + 1) % mod * (len + len + 1) % mod * kuai(6, mod - 2) % mod;int v2 = (len + 1) * len % mod * kuai(2, mod - 2) % mod;// ans += len * (len + 1) * (len + len + 1) / 6;// ans += (len + 1) * len / 2;ans = v1 + v2;ans %= mod;return ans;}int n1 = r1 - l1 + 1, n2 = r2 - l2 + 1;int sum1 = (l1 + r1) % mod * n1 % mod * kuai(2, mod - 2) % mod;int sum2 = (l2 + r2) % mod * n2 % mod * kuai(2, mod - 2) % mod;int aaa = n1 * sum2 % mod - n2 * sum1 % mod;aaa %= mod;aaa += mod;aaa %= mod;ans = aaa;return ans;
}int dfs(const PII &q1, const PII &q2) {int ans = 0;ans = dfs(q1.first, q1.second, q2.first, q2.second);return ans % mod;
}int solve(int l1,int r1,int l2,int r2) {if (l1 > l2) {swap(l1, l2);swap(r1, r2);}else {if (l1 == l2) {if (r1 > r2) {swap(l1, l2);swap(r1, r2);}}}if (l1 == l2 and r1 == r2) {return dfs(l1, r1, l2, r2);}if (r1 < l2) {return dfs(l1, r1, l2, r2);}if (l1 <= l2 and r2 < r1) {PII q1, q2, q3;q1 = {l1, l2 - 1};q2 = {l2, r2};q3 = {r2 + 1, r1};int ans = 0;ans += dfs(q1, q2);ans %= mod;ans += dfs(q2, q2);ans %= mod;ans += dfs(q3, q2);ans %= mod;return ans;}if (l2 <= r1 and r1 <= r2) {PII q1, q2, q3;q1 = {l1, l2 - 1};q2 = {l2, r1};q3 = {r1 + 1, r2};int ans = 0;ans += dfs(q1, q2);ans %= mod;ans += dfs(q1, q3);ans %= mod;ans += dfs(q2, q2);ans %= mod;ans += dfs(q2, q3);ans %= mod;return ans;}return dfs(l1, r1, l2, r2);}int solve(const PII &q1, const PII &q2) {return solve(q1.first, q1.second, q2.first, q2.second);
}PII A[N];signed main() {fileRead();kuaidu();T = 1;cin >> T;while (T--) {cin >> n;int nums = 1;rep(i, 1, n) {cin >> A[i].first;cin >> A[i].second;nums *= (A[i].second - A[i].first + 1);nums %= mod;}int v1, c1, v2, c2;c1 = A[1].second - A[1].first + 1;v1 = solve(A[1], A[2]);// cc(v1);rep(i, 3, n) {c2 = A[i].second - A[i].first + 1;v2 = solve(A[i - 1], A[i]);// cc(i, c1, v1);v1 = v1 * c2 % mod + v2 * c1 % mod;v1 %= mod;c1 *= (A[i - 1].second - A[i - 1].first + 1);c1 %= mod;// cc(v1);}auto kuai = Kuai<mod>;if (nums == 0) {cout << "sadasdaas" << endl;continue;}int ans = v1 * kuai(nums, mod - 2) % mod;// cc(v1);cc(ans);}return 0;
}/*
1
5
3 4
2 5
2 9
1 1
10 14*/

Problem B. Tokitsukaze and Balance String(easy)

请转战到C题

Problem C. Tokitsukaze and Balance String (hard)

多写几组数据找找规律,就会发现抛开两侧的不谈,剩余的中间的部分所做的贡献是一样的并且都是固定的,如果设除去两侧,剩余的部分的问号的个数是\(c\),那么他们的贡献的和便是kuai(2, c) * (s.size() - 2),也就是说每一个位置的贡献是2的c次方。然后再考虑上两侧的四种情况,分情况去讨论输出答案就好了。

//--------------------------------------------------------------------------------
const int N = 1e5 + 10;
const int M = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 1e16;
int n, m, T;//--------------------------------------------------------------------------------
//struct or namespace:auto kuai = Kuai<mod>;
//--------------------------------------------------------------------------------signed main() {fileRead();kuaidu();T = 1;cin >> T;while (T--) {string s;cin >> n;cin >> s;if (n == 1) {if (s == "?") cc(2);else cc(1);continue;}int c = 0;for (auto &x: s) {if (x == '?') c += 1;}// c -= 2;int len = s.size();if (s[0] == '?') c -= 1;if (s[len - 1] == '?') c -= 1;int ans = 0;if (s[0] == '?' and s[len - 1] == '?') {ans += 2 * kuai(2, c) % mod * s.size() % mod;}else if (s[0] != '?' and s[len - 1] != '?') {if (s[0] == s[len - 1]) {ans += kuai(2, c) * (s.size() - 2) % mod;}else {ans += 2 * kuai(2, c) % mod;}}else {ans += kuai(2, c) % mod * s.size() % mod;}cc(ans);}return 0;
}/**/

Problem D. Tokitsukaze and Concatenate‌ Palindrome

首先将长度比较长的设成字符串a,短的是字符串b。

先考虑一种简单的情况。如果b是a的子集,那直接a去掉b的所剩余的字符集中把每一个字符的个数%2,再求和,最后/2(向下取整,相当于我们改掉那一半的个数,便能得到回文串了)便是答案。那如果不是呢?

那么如果a不是完全包于b。也就是说如果b中间有一些字符a没有的话,那么我们是一定要加上这个部分的贡献的。我们设这一部分的贡献是sum2。那记录下来字符串a中已经去除了b的部分的剩余的字符的数%2的和,设这个是sum。那先考虑当sum是大于sum2的情况下,既然我们已经先要选择当sum2个字母改变了,那现在还差sums-sum2个字母去得到回文串,所以我们就还要再加上这个差值的一半,修改差值的一半的字母。也能够得到一个完整的回文串。

那如果是小于的情况呢,那显然我们就根本就不需要再操作就好了。

//--------------------------------------------------------------------------------
const int N = 1e5 + 10;
const int M = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 1e16;
int n, m, T;
map<char,int> mp, mp2;
//--------------------------------------------------------------------------------
//struct or namespace://--------------------------------------------------------------------------------signed main() {fileRead();kuaidu();T = 1;cin >> T;while (T--) {cin >> n >> m;string s1, s2;cin >> s1 >> s2;mp.clear();mp2.clear();if (n < m) {swap(n, m);swap(s1, s2);}for (auto &x: s1) {mp[x] += 1;}for (auto &x: s2) {mp[x] -= 1;}int sum = 0, sum2 = 0;for (auto [a,b]: mp) {if (b < 0) {sum2 += -b;}}int ans = 0;ans += sum2;for (auto [a,b]: mp) {if (b < 0) continue;sum += b % 2;}if (sum >= sum2) {ans += (sum - sum2) / 2;}else {}cc(ans);}return 0;
}/**/

Problem E. Tokitsukaze and Dragon's Breath

先把每一个左对角线的全局之和搜索到,然后再将其赋值到每一个坐标中。右对角线也是这样子去做。

那么我们就得到了对于当前这一个点来说展开的左对角线之和和右对角线之和分别是多少。

那么我们加上这两个权值再减去当前这个点便是这个点的贡献取出贡献的最大值就好了

//--------------------------------------------------------------------------------
const int N = 1e3 + 10;
const int M = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 1e16;
int n, m, T;
int A[N][N];
int you[N][N]; // /
int zuo[N][N]; // \
//--------------------------------------------------------------------------------
//struct or namespace://--------------------------------------------------------------------------------
int dfs(int x,int y,int dx,int dy) {if (x < 1 or y < 1 or x > n or y > m) return 0;int val = 0;val += dfs(x + dx, y + dy, dx, dy);val += A[x][y];return val;
}void fuzhi(int x,int y,int dx,int dy,int zong) {if (x < 1 or y < 1 or x > n or y > m) return;fuzhi(x + dx, y + dy, dx, dy, zong);if (dx == 1 and dy == 1) zuo[x][y] = zong;else you[x][y] = zong;
}signed main() {fileRead();kuaidu();T = 1;cin >> T;while (T--) {cin >> n >> m;rep(i, 1, n)rep(j, 1, m) {cin >> A[i][j];zuo[i][j] = 0;you[i][j] = 0;}rep2(j, m, 1) {int val = dfs(1, j, 1, 1);fuzhi(1, j, 1, 1, val);}rep(i, 2, n) {int val = dfs(i, 1, 1, 1);fuzhi(i, 1, 1, 1, val);}rep(j, 1, m) {int val = dfs(1, j, 1, -1);fuzhi(1, j, 1, -1, val);}rep(i, 2, n) {int val = dfs(i, m, 1, -1);fuzhi(i, m, 1, -1, val);}int ans = -INF;rep(i, 1, n) {rep(j, 1, m) {cmax(ans, zuo[i][j] + you[i][j] - A[i][j]);}}cc(ans);}return 0;
}

Problem F. Tokitsukaze and Kth Problem (easy)

非常典的一道题,只能说没有时间去做了,有点可惜。忘了是在哪里,之前的牛客周赛上还是在哪里有出过这种类似的题。

我们先对他取模p那么任意两个数的和一定会小于2p。我们的做法就先把原本的数组取模然后从小到大排个序。就可以用双指针的方法去解决这一类问题。

首先我们先用二分找到第k大的数是几,然后再用双指针去搜索,将其每一个遍历放到vec ans即可最后直接输出就好了。

	rep(i, 1, n) {while (r1 and A[i] + A[r1] >= r) r1--;while (r2 and A[i] + A[r2] >= r + mod) r2--;rep(j, max(i+1,r1+1), n) {if (A[i] + A[j] >= mod) break;ans.push_back(A[i] + A[j]);}rep(j, max(i+1,r2+1), n) {ans.push_back((A[i] + A[j]) % mod);}}

这个里面嵌套的for循环是存储答案的。

关于这个时间复杂度的证明,因为k<=2e5,我们在这一部分执行也会小于等于k,所以时间复杂度就不会是N方级别的,就没有问题。

//--------------------------------------------------------------------------------
const int N = 2e5 + 10;
const int M = 1e6 + 10;
// const int mod = 1e9 + 7;
int mod;
const int INF = 1e16;
int n, m, T;
int k;
int A[N];//--------------------------------------------------------------------------------
//struct or namespace://--------------------------------------------------------------------------------//特判全都输出的情况
void out() {vec<int> ans;rep(i, 1, n) {rep(j, i+1, n) {ans.push_back((A[i] + A[j]) % mod);}}while (ans.size() < k) ans.push_back(-1);sort(ans.begin(), ans.end(), [](int a, int b) { return a > b; });cc(ans);
}signed main() {fileRead();kuaidu();T = 1;cin >> T;while (T--) {cin >> n >> mod >> k;rep(i, 1, n) {cin >> A[i];A[i] %= mod;}sort(A + 1, A + n + 1);if (n * (n - 1) / 2 <= k) {out();continue;}auto get = [&](int x)-> int {int ans = 0;int r = n;rep(i, 1, n) {while (r and A[i] + A[r] >= x) r--;if (r > i) ans += n - r;else ans += n - i;}return ans;};//大于等于mid的个数auto check = [&](int mid)-> int {return get(mid) + get(mid + mod) - get(mod);};int l = 0, r = mod;while (l + 1 != r) {int mid = (l + r) >> 1;if (check(mid) >= k) l = mid;else r = mid;}// cc(l);vec<int> ans;int r1 = n, r2 = n;rep(i, 1, n) {while (r1 and A[i] + A[r1] >= r) r1--;while (r2 and A[i] + A[r2] >= r + mod) r2--;rep(j, max(i+1,r1+1), n) {if (A[i] + A[j] >= mod) break;ans.push_back(A[i] + A[j]);}rep(j, max(i+1,r2+1), n) {ans.push_back((A[i] + A[j]) % mod);}}sort(ans.begin(), ans.end(), [](int a, int b) { return a > b; });while (ans.size() < k) ans.push_back(l);cc(ans);// cc(ans2);}return 0;
}/**/

Problem I. Tokitsukaze and Pajama Party

我觉得这个题并没有那么的签到。 根据题意,我们每一次找到后面这个长串的字符串的时候就往前找有多少一个\(u\)字符就可以了,但是注意要去掉相邻的。

//--------------------------------------------------------------------------------
const int N = 1e5 + 10;
const int M = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 1e16;
int n, m, T;//--------------------------------------------------------------------------------
//struct or namespace://--------------------------------------------------------------------------------signed main() {fileRead();kuaidu();T = 1;cin >> T;while (T--) {cin >> n;string s;cin >> s;int sum = 0;int ans = 0;rep(i, 0, n-1) {string s1 = "";rep(j, 0, 7) {if (i + j <= n - 1)s1 = s1 + s[i + j];}if (s1 == "uwawauwa") {ans += sum;if (i - 1 >= 0 and s[i - 1] == 'u') ans -= 1;}if (s[i] == 'u') sum++;}cc(ans);}return 0;
}

Problem J. Tokitsukaze and Recall

终于出图论了,难度应该是有铜弱难度的。

大概的思路是,我们可以花费一代价将一个并查集里面的点全部都访问到。所以我们按理来说应该要先将并查集根据大小从大到小排列,然后优先遍历个数大的,但是我们并查集中还要维护一个最小的编号。当个数相同的时候就优先遍历编号小的那一个。但是这样子做的话样例会有过不去的,因为如果我们有多余的价值,我们可以去优先访问到我们没有访问到的最小编号,就例如一号编号和二号编号在同一个并查集。 假设我们有多余的代价,我们就可以在访问一号编号之后去强制访问二号编号。直接将这个特殊判断写到我们的 BFS 当中就好了。

有一个细节注意:我们不能直接将剩余的代价从编号一到N依次遍历,如果没有放入我们的队列中我们就把它放进去。最后直接跑一个普通BFS。

这样的做法是错误的,因为如果一号编号和二号编号它们是相邻的情况下这样的做法将不对。

//--------------------------------------------------------------------------------
const int N = 2e5 + 10;
const int M = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 1e16;
int n, m, T;//--------------------------------------------------------------------------------
//struct or namespace:namespace z {struct ED {int y;int val;};vector<ED> A[N];int son[N], dep[N];void clear(const int &n) {rep(i, 1, n) {A[i].clear();}}void add(const int &x, const int &y, int c = 1) {A[x].push_back({y, c});}
};class DSU {struct Info {int fa;int siz;int mmin;} dsu[N];public:Info &operator()(const int &x) { return dsu[find(x)]; }Info &operator[](const int &x) { return dsu[x]; }void clear(int n) {//TODO 初始化rep(i, 1, n) dsu[i].fa = i, dsu[i].siz = 1, dsu[i].mmin = i;}void merge(int x, int y) {x = find(x), y = find(y);if (x == y) return;dsu[y].fa = dsu[x].fa;if (dsu[x].siz < dsu[y].siz) swap(dsu[x], dsu[y]);dsu[y].fa = dsu[x].fa, dsu[x].siz += dsu[y].siz;cmin(dsu[x].mmin, dsu[y].mmin);//TODO 合并操作}int find(int x) { return x == dsu[x].fa ? x : dsu[x].fa = find(dsu[x].fa); }bool same(int x, int y) { return (find(x) == find(y)); }
} dsu;int k;
bool vis[N], vis2[N];
//--------------------------------------------------------------------------------signed main() {fileRead();kuaidu();T = 1;cin >> T;while (T--) {cin >> n >> m >> k;dsu.clear(n);z::clear(n);rep(i, 1, n) {vis[i] = 0;vis2[i] = 0;}rep(i, 1, m) {int a, b;cin >> a >> b;dsu.merge(a, b);z::add(a, b);z::add(b, a);}vec<PII> tem;rep(i, 1, n) {if (dsu.find(i) == i) {tem.push_back({dsu[i].siz, dsu[i].mmin});}}sort(tem.begin(), tem.end(), [](const PII &q1, const PII &q2) {if (q1.first == q2.first) return q1.second < q2.second;return q1.first > q2.first;});priority_queue<int> F;int cnt = 0;for (auto &[siz,x]: tem) {cnt++;if (cnt <= k) {F.push(-x);vis[x] = 1;}}k -= cnt;cmax(k, 0);vec<int> ans;int now = 0;while (!F.empty()) {auto x = F.top();x = -x;if (abs(now - x) > 1 and k) {k--;F.push(-(now + 1));continue;}now = x;F.pop();if (vis2[x]) continue;vis2[x] = 1;ans.push_back(x);for (auto &[y,val]: z::A[x]) {if (vis2[y]) continue;F.push(-y);}}cc(ans.size());cc(ans);}return 0;
}/**/

Problem K. Tokitsukaze and Shawarma

纯纯签到题

//--------------------------------------------------------------------------------
const int N = 1e5 + 10;
const int M = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 1e16;
int n, m, T;//--------------------------------------------------------------------------------
//struct or namespace://--------------------------------------------------------------------------------signed main() {fileRead();kuaidu();T = 1;cin >> T;while (T--) {int x, y, z, a, b, c;cin >> x >> y >> z >> a >> b >> c;int mmax = 0;cmax(mmax, a * x);cmax(mmax, b * y);cmax(mmax, c * z);cc(mmax);}return 0;
}/**/

Problem L. Tokitsukaze and XOR-Triangle

数据结构题,非常典型的一个trick就是按位去考虑。考虑二进制的形式,将每一个数拆成三十个位置,对于每一个位置分开计算,最后在将答案加起来就好了。

那么接下来每一个数字将会是零或者是一,这个题就变成了简单的查询区间内0,1的个数和。

用前缀和的形式去做就好了,具体的式子就写到代码里了。

		de = getb0(j, l, r) * geta1(j, 1, l - 1) % mod + getb1(j, l, r) * geta0(j, 1, l - 1) % mod;de %= mod;int tem = (ans[j][r] - ans[j][l - 1] - de) % mod + mod;

get函数是求出二进制中第j位区间内0或者1的个数的和。

贡献是tem。

//--------------------------------------------------------------------------------
const int N = 3e5 + 10;
const int M = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 1e16;
int n, m, T;//--------------------------------------------------------------------------------
//struct or namespace:
int pre_a0[32][N];
int pre_a1[32][N];
int pre_b0[32][N];
int pre_b1[32][N];
int ans[32][N];
int A[N], B[N];int geta0(int k,int l,int r) {return pre_a0[k][r] - pre_a0[k][l - 1];
}int geta1(int k,int l,int r) {return pre_a1[k][r] - pre_a1[k][l - 1];
}int getb0(int k,int l,int r) {return pre_b0[k][r] - pre_b0[k][l - 1];
}int getb1(int k,int l,int r) {return pre_b1[k][r] - pre_b1[k][l - 1];
}int solve(int l,int r) {int res = 0;rep(j, 0, 30) {int de = 0;de = getb0(j, l, r) * geta1(j, 1, l - 1) % mod + getb1(j, l, r) * geta0(j, 1, l - 1) % mod;de %= mod;int tem = (ans[j][r] - ans[j][l - 1] - de) % mod + mod;tem %= mod;res += tem * (1ll << j) % mod;res %= mod;}return res;
}//--------------------------------------------------------------------------------signed main() {fileRead();kuaidu();T = 1;cin >> T;while (T--) {int q;cin >> n >> q;rep(i, 1, n) {cin >> A[i];}rep(i, 1, n) {cin >> B[i];}rep(j, 0, 30) {rep(i, 1, n) {pre_a0[j][i] = 0;pre_a1[j][i] = 0;pre_b0[j][i] = 0;pre_b1[j][i] = 0;ans[j][i] = 0;}}rep(j, 0, 30) {rep(i, 1, n) {pre_a0[j][i] += pre_a0[j][i - 1];if (A[i] >> j & 1) pre_a0[j][i] += 0;else pre_a0[j][i] += 1;pre_a1[j][i] += pre_a1[j][i - 1];if (A[i] >> j & 1) pre_a1[j][i] += 1;pre_b0[j][i] += pre_b0[j][i - 1];if (B[i] >> j & 1) pre_b0[j][i] += 0;else pre_b0[j][i] += 1;pre_b1[j][i] += pre_b1[j][i - 1];if (B[i] >> j & 1) pre_b1[j][i] += 1;}}rep(j, 0, 30) {rep(i, 1, n) {ans[j][i] += ans[j][i - 1];ans[j][i] %= mod;if (B[i] >> j & 1) {ans[j][i] += geta0(j, 1, i);ans[j][i] %= mod;}else {ans[j][i] += geta1(j, 1, i);ans[j][i] %= mod;}}}rep(i, 1, q) {int l, r;cin >> l >> r;cc(solve(l, r));}}return 0;
}/**/

PostScript

阿巴巴阿巴

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/880316.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Proj CJI Paper Reading: Detecting language model attacks with perplexity

AbstractTool: PPL Findings:queries with adversarial suffixes have a higher perplexity, 可以利用这一点检测 仅仅使用perplexity filter对mix of prompt types不合适,会带来很高的假阳率Method: 使用Light-GDB根据perplexity和token length filter带有adversarial suffix…

年化收益17倍的红中探底(单针探底)操作策略

作者QQ: 396068801,加Q分享交流通达信红中探底指标。 红中探底条件: # 更新日志:# 2025-2-7 改为红中创10天新低,25日均线向上,尾盘进。# 止盈操作:涨停不卖, 每涨8%就卖一半,直到浮盈达到3倍清仓;高点跌8%清仓。# 止损: 买入后只要跌超6%就清仓止损。# 卖票时间: …

Java基础学习(十五)

Java基础学习(十五):IO流 目录Java基础学习(十五):IO流概念基本流字节输出流 FileOutputStream字节输入流 FileInputStream字符集Java 中的编码和解码字符输入流 FileReader字符输出流 FileWriter缓冲流字节缓冲流字符缓冲流转换流序列化流 和 反序列化流序列化流反序列化…

linux vm tools 问题

转载vmware tools 失效问题解决方式(Ubuntu 22 以及其他系统) - 知乎 今天新装了Kubuntu 以及 Ubuntu 版本均为 22x,一如既往的操作,最后发现VMware tools失效。 尝试输入vmware-user发现又可以了。 具体表现: 1、窗口分辨率可以缩放,无法复制粘贴,无法复制粘贴文件。 2…

【shell脚本】轻松搞定打包与Shell部署

本篇和大家分享的是springboot打包并结合shell脚本命令部署,重点在分享一个shell程序启动工具,希望能便利工作; 1. profiles指定不同环境的配置 通常一套程序分为了很多个部署环境:开发,测试,uat,线上 等,我们要想对这些环境区分配置文件,可以通过两种方式: 1、通过a…

01 HTML详解

一. HTML语言 HTML是超文本标记语言。超文本:文本、图片、声音、视频、表格、链接等等。 标记:由许许多多的标签组成。二. HTML结构 HTML 代码是由 "标签" 构成的。 形如: <body>hello</body>标签名 (body) 放到 < > 中。大部分标签成对出现。…

HTML详解

一. HTML语言 HTML是超文本标记语言。超文本:文本、图片、声音、视频、表格、链接等等。 标记:由许许多多的标签组成。二. HTML结构 HTML 代码是由 "标签" 构成的。 形如: <body>hello</body>标签名 (body) 放到 < > 中。大部分标签成对出现。…

【Nginx】Nginx 配置页面请求不走缓存 浏览器页面禁用缓存

我是Superman丶 巴韭特锁螺丝 2025年02月07日 08:50 陕西 前言 使用缓存的优点在于减少数据传输,节省网络流量,加快响应速度;减轻服务器压力;提供服务端的高可用性;缺点在于数据的不一致问题;增加成本 Nginx作为Web缓存服务器,介于客户端和应用服务器之间,当用户通过浏…

NLog日志(三)

程序开发日志输出常用逻辑 1.应用启动和关闭添加新配置<rules><!-- 默认日志记录器(仅控制台输出) --><logger name="*" minlevel="Debug" writeTo="logconsole" /><!-- 记录应用启动 & 关闭日志 --><logger n…

XXL-CACHE v1.2.0 | 多级缓存框架

Release Notes1、【增强】多序列化协议支持:针对L2缓存,组件化抽象Serializer,可灵活扩展更多序列化协议; 2、【优化】移除冗余依赖,精简Core体积;XXL- CACHE 快速接入示例代码参考github仓库 /test 目录:https://github.com/xuxueli/xxl-cache/tree/master/xxl-cache-s…

将模型api集成到python中

1.今日成果 1-1从阿里百炼上获取使用API的代码,在本地配置好环境,运行。 1-2ollama上拉取视频理解的模型,却没有上传视频的界面,可以使用python代码加载模型 1-3huggingface上的模型可以通过transformer集成到python运行。 1-4Qwen模型本地部署的环境搭建好了 2.未解决的问…

注解反射之使用Class对象获取注解

代码如下package com.loubin;import java.lang.annotation.*; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;public class Main {public static void main(S…