随笔 - 164  文章 - 0  评论 - 4  阅读 - 9757

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

思维诈骗题!!!题目具有特殊性
对于式子 a=min(x,ri+lix),b=max(x,ri+lix) 表示的区间 [a, b] 即为区间 [li,ri] 中,x 到关于本区间对称位 x1 的子区间。
lili+rixri(x+li+rix)/2=(li+ri)/2,所以对称
所以所有的翻转都是对称翻转,而且各翻转区间 [li,ri] 之间互不影响
所以利用差分数组统计每个位置上的翻转次数,翻转奇数次输出对称位,偶数次输出本位即可

//>>>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;
}
posted on   Qiansui  阅读(49)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示