题目
给一个长度为n的数组,总权值和为val, 期望是否能找到一个区间[l,r](r - l + 1 < n),使得区间[l, r]的权值和大于等于val,可能有某个元素值可以为负数。
为了省事,直接线段树暴力求某个区间的最大值。
#include<bits/stdc++.h>
using namespace std;
int N = 200005;
int tr[200015], f[50004], a[50004], add[200015];
void pushup(int root){
tr[root] = max(tr[root << 1], tr[root << 1 | 1]);
}
void pushdown(int root){
add[root << 1] += add[root];
add[root << 1 | 1] += add[root];
tr[root << 1] += add[root];
tr[root << 1 | 1] += add[root];
add[root] = 0;
}
void build(int l, int r, int root){
if(l == r){
tr[root] = f[l];
return;
}
int mid = l + r >> 1;
build(l, mid, root << 1);
build(mid + 1, r , root << 1 | 1);
pushup(root);
}
void undate(int l, int r, int root, int L, int R, int val){
if(L <= l && R >= l){
tr[root] += val;
add[root] += val;
return ;
}
pushdown(root);
int mid = l + r >> 1;
if(L <= mid) undate(l, mid, root << 1, L, R, val);
if(R > mid) undate(mid + 1, r, root << 1 | 1, L, R, val);
pushup(root);
}
int query(int l, int r, int root, int L, int R){
if(L <= l && R >= r){
return tr[root];
}
int ans = -1000000000, mid = l + r >> 1;
pushdown(root);
if(L <= mid) ans = max(ans, query(l, mid, root << 1, L, R));
if(R > mid) ans = max(ans, query(mid + 1, r, root << 1 | 1, L, R));
return ans;
}
int main(){
int t, n;
cin >> t;
while(t--){
cin >> n;
f[0] = 0;
int flag = 0;
memset(tr, 0, sizeof(tr));
memset(add, 0, sizeof(add));
for(int i = 1; i <= n; i++){
cin >> a[i];
f[i] = a[i] + f[i - 1];
}
build(1, n - 1, 1);
for(int i = 1; i <= n - 1; i++){
int k = query(1, n - 1, 1, i, n - 1);
if(k >= f[n]){
flag = 1;
break;
}
undate(1, n - 1, 1, i, n - 1, -a[i]);
}
int val = f[n];
for(int i = 1; i <= n - 1; i++){
f[n] -= a[i];
if(f[n] >= val){
flag = 1;
break;
}
}
flag == 1 ? cout << "Yes" << endl : cout << "No" << endl;
}
return 0;
}
求汉明距离
给两个01串\(s\)和\(t\),\(|t|\le |s|\), 想知道\(t\)和\(s\)中所有长度为\(t\)的子串的汉明距离之和
输入样例
01
00111
输出
3
#include<bits/stdc++.h>
using namespace std;
string t, s;
int main(){
cin >> t >> s;
int n = s.size();
int m = t.size();
bitset<50000> o1, o2, o3;
int ans = 0, pos = 49999;
for(int i = 0; i < m; i++){
if(t[i] == '1') o2.set(pos - i);
}
for(int i = 0; i < m; i++){
if(s[i] == '1') o1.set(pos - i);
}
o3 = o1 ^ o2;
ans += o3.count();
//cout << "o1" << " " << o1 << endl;
//cout << "o2" << " " << o2 << endl;
//cout << "o3" << " " << o3 << endl;
//cout << "------------------------------" << endl;
for(int i = m; i < n; i++){
o1 <<= 1;
if(s[i] == '1') o1.set(pos - m + 1);
o3 = o1 ^ o2;
ans += o3.count();
//cout << "o1" << " " << o1 << endl;
//cout << "o2" << " " << o2 << endl;
//cout << "o3" << " " << o3 << endl;
//cout << "------------------------------" << endl;
}
cout << ans << endl;
return 0;
}