T1 CF1607E
简单题,直接模拟即可。
T2 CF1614C
容易发现一种可行的构造方案就是对于每个 \(a_i\) 以及包含它的操作 \(C_{i_1, i_2 ... i_t}\),令 \(a_i = V_{i_1} \& V_{i_2} \& ...V_{i_t}\) 即可。直接硬上线段树即可。
考虑到位运算位之间互不影响的性质,接着我们从分别考虑每一位对答案的贡献。统计的时候分类讨论一下就可以了。
qwq
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 10, mod = 1e9 + 7;
int n, m, a[N], two[50];
namespace Segtree{
#define ls (o << 1)
#define rs (o << 1 | 1)
#define mid (l + r >> 1)
int tag[N << 2];
void build(int o, int l, int r){
tag[o] = (1ll << 31) - 1;
if(l == r) return;
build(ls, l, mid); build(rs, mid + 1, r);
}
void pushdown(int o){
if(tag[o] != (1ll << 31) - 1){
tag[ls] &= tag[o]; tag[rs] &= tag[o];
tag[o] = (1ll << 31) - 1;
}
}
void addtag(int o, int l, int r, int s, int t, int val){
if(s <= l && r <= t){tag[o] &= val; return;}
pushdown(o);
if(s <= mid) addtag(ls, l, mid, s, t, val);
if(mid < t) addtag(rs, mid + 1, r, s, t, val);
}
void getval(int o, int l, int r){
if(l == r){a[l] = tag[o]; return;}
pushdown(o); getval(ls, l, mid); getval(rs, mid + 1, r);
}
}
using namespace Segtree;
int calc(int bitid){
int cnt[2] = {1, 0};
for(int i = 1; i <= n; i++){
bool f = (a[i] & (1 << bitid));
int c[2]; c[0] = (cnt[0] + cnt[f]) % mod; c[1] = (cnt[1] + cnt[f ^ 1]) % mod;
cnt[0] = c[0]; cnt[1] = c[1];
}
return cnt[1];
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int T; cin >> T; two[0] = 1;
for(int i = 1; i <= 40; i++) two[i] = (two[i - 1] * 2) % mod;
while(T--){
cin >> n >> m; build(1, 1, n);
for(int i = 1; i <= m; i++){
int l, r, v; cin >> l >> r >> v;
addtag(1, 1, n, l, r, v);
}
getval(1, 1, n); int ans = 0;
// for(int i = 1; i <= n; i++) cout << a[i] << " ";
// cout << calc(0) << "\n";
for(int bit = 0; bit <= 30; bit++) ans = (ans + calc(bit) * two[bit] % mod) % mod;
cout << ans << "\n";
}
return 0;
}