Codeforces Round 900 (Div. 3) - A B C D(差分) E(静态区间查询 + 二分)
目录
A. How Much Does Daytona Cost?
判断数 k 包不包含在数组里面即可
B. Aleksa and Stack
法一:选定初始数为2, 3,后面的从 4 开始遍历,逐项比较更新答案即可
法二:全奇数即可,因为奇数 + 奇数 = 偶数,奇数 x 3 = 奇数,奇数肯定不能被偶数整除
C. Vasilije in Cacak
等差数列中选 k 个数,最小和为前 k 个数的和,最大和为后 k 个数的和,之间的一定能取到
D. Reverse Madness
思维诈骗题!!!题目具有特殊性
对于式子
所以所有的翻转都是对称翻转,而且各翻转区间
所以利用差分数组统计每个位置上的翻转次数,翻转奇数次输出对称位,偶数次输出本位即可
//>>>Qiansui #include<bits/stdc++.h> #define ll long long #define ull unsigned long long #define mem(x,y) memset(x, y, sizeof(x)) #define debug(x) cout << #x << " = " << x << '\n' #define debug2(x,y) cout << #x << " = " << x << " " << #y << " = "<< y << '\n' //#define int long long using namespace std; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef pair<ull, ull> pull; typedef pair<double, double> pdd; /* */ const int maxm = 2e5 + 5, inf = 0x3f3f3f3f; const ll INF = 0x3f3f3f3f3f3f3f3f, mod = 998244353; string ss; int n, k, l[maxm], r[maxm], q; void solve(){ cin >> n >> k >> ss; for(int i = 1; i <= k; ++ i) cin >> l[i]; for(int i = 1; i <= k; ++ i) cin >> r[i]; vector<int> d(n + 10, 0); cin >> q; while(q--){ int x; cin >> x; auto id = lower_bound(r + 1, r + k + 1, x) - r; int a = min(x, r[id] + l[id] - x), b = max(x, r[id] + l[id] - x); ++ d[a]; -- d[b + 1]; } ss = ' ' + ss; for(int i = 1; i <= k; ++ i){ for(int j = l[i]; j <= r[i]; ++ j){ d[j] += d[j - 1]; if(d[j] % 2){ cout << ss[l[i] + r[i] - j ]; }else cout << ss[j]; } } cout << '\n'; return ; } signed main(){ ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); int _ = 1; cin >> _; while(_ --){ solve(); } return 0; }
E. Iva & Pav
唯一的问题就是怎么快速的求得区间 [l, r] 的位与值
可以得知从前往后位与,值一定是单调递减的
方法一:线段树区间查询
阿巴阿巴,线段树基础,没啥好说的
//>>>Qiansui #include<bits/stdc++.h> #define ll long long #define ull unsigned long long #define mem(x,y) memset(x, y, sizeof(x)) #define debug(x) cout << #x << " = " << x << '\n' #define debug2(x,y) cout << #x << " = " << x << " " << #y << " = "<< y << '\n' //#define int long long using namespace std; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef pair<ull, ull> pull; typedef pair<double, double> pdd; /* */ const int maxm = 2e5 + 5, inf = 0x3f3f3f3f; const ll INF = 0x3f3f3f3f3f3f3f3f, mod = 998244353; int n, a[maxm], q; struct Segment_Tree{//update - range_& + query - range_& int n; vector<ll> seg, tag; Segment_Tree(int cnt) : n(cnt), seg(cnt << 2, 0), tag(cnt << 2, 0){} int ls(int p) { return p << 1; } int rs(int p) { return p << 1 | 1; } void push_up(int p){ seg[p] = seg[ls(p)] & seg[rs(p)]; return ; } void build(int p, int pl, int pr){ tag[p] = 0; if(pl == pr){ seg[p] = a[pl]; return ; } int mid = pl + pr >> 1; build(ls(p), pl, mid); build(rs(p), mid + 1, pr); push_up(p); return ; } void addtag(int p, int pl, int pr, ll k){ tag[p] += k; seg[p] += (pr - pl + 1) * k; return ; } void push_down(int p, int pl, int pr){ if(tag[p]){ int mid = pl + pr >> 1; addtag(ls(p), pl, mid, tag[p]); addtag(rs(p), mid + 1, pr, tag[p]); tag[p] = 0; } return ; } void update(int p, int pl, int pr, int l, int r, ll k){ if(l <= pl && pr <= r){ addtag(p, pl, pr, k); return ; } push_down(p, pl, pr); int mid = pl + pr >> 1; if(l <= mid) update(ls(p), pl, mid, l, r, k); if(mid < r) update(rs(p), mid + 1, pr, l, r, k); push_up(p); return ; } ll query(int p, int pl, int pr, int l, int r){ if(l <= pl && pr <= r){ return seg[p]; } push_down(p, pl, pr); ll res = 0; res = ~res; int mid = pl + pr >> 1; if(l <= mid) res &= query(ls(p), pl, mid, l, r); if(mid < r) res &= query(rs(p), mid + 1, pr, l, r); return res; } }; void solve(){ cin >> n; vector<ll> f(n + 1); for(int i = 1; i <= n; ++ i){ cin >> a[i]; } Segment_Tree tr(n); tr.build(1, 1, n); cin >> q; while(q --){ int l, k; cin >> l >> k; int x = l, y = n, mid; while(x <= y){ mid = (x + y) >> 1; if(tr.query(1, 1, n, l, mid) >= k) x = mid + 1; else y = mid - 1; } if(y < l) cout << -1 << ' '; else cout << y << ' '; } cout << '\n'; return ; } signed main(){ ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); int _ = 1; cin >> _; while(_ --){ solve(); } return 0; }
方法二:倍增预处理
//>>>Qiansui #include<bits/stdc++.h> #define ll long long #define ull unsigned long long #define mem(x,y) memset(x, y, sizeof(x)) #define debug(x) cout << #x << " = " << x << '\n' #define debug2(x,y) cout << #x << " = " << x << " " << #y << " = "<< y << '\n' //#define int long long using namespace std; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef pair<ull, ull> pull; typedef pair<double, double> pdd; /* */ const int maxm = 2e5 + 5, inf = 0x3f3f3f3f, lgn = 20; const ll INF = 0x3f3f3f3f3f3f3f3f, mod = 998244353; int n, a[maxm]; void solve(){ cin >> n; vector f(n + 1, vector<int> (lgn, 0)); vector p(n + 1, vector<int> (lgn, n)); for(int i = 1; i <= n; ++ i){ cin >> a[i]; } for(int i = 1; i < n; ++ i){ f[i][0] = a[i + 1]; p[i][0] = i + 1; } for(int j = 1; j < lgn; ++ j){ for(int i = n - (1 << j) + 1; i > 0; -- i){ f[i][j] = f[i][j - 1] & f[p[i][j - 1]][j - 1]; p[i][j] = p[p[i][j - 1]][j - 1]; } } int q; cin >> q; while(q --){ int l, k; cin >> l >> k; if(a[l] >= k){ int t = a[l], r = l; for(int i = lgn - 1; i >= 0; -- i){ if((t & f[r][i]) >= k){ t = t & f[r][i]; r = p[r][i]; } } cout << r << ' '; }else{ cout << -1 << ' '; } } cout << '\n'; return ; } signed main(){ ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); int _ = 1; cin >> _; while(_ --){ solve(); } return 0; }
本文来自博客园,作者:Qiansui,转载请注明原文链接:https://www.cnblogs.com/Qiansui/p/17734369.html
分类:
oj - Codeforces
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效