【题解】ARC133D - Range XOR
作者:互联网
我们先求个前缀和 \(s_i = \bigoplus\limits_{x = 1}^ix\),问题转化为求满足 \(L - 1 \le l < r \le R\) 且 \(s_r \oplus s_l = V\) 的二元组 \((l,r)\) 个数。
对于 \(s_i\),不难发现以 \(4\) 为循环有固定的规律:\(s_{4x} = 4x,s_{4x+1} = 1, s_{4x+2} = 4x+3, s_{4x+3} = 0\)。
所以我们可以将 \(V / 4\) 和 \(V\bmod 4\) 分开计算,枚举 \(l \bmod 4\) 和 \(r \bmod 4\),然后计算有多少 \(l/4\) 和 \(r/4\) 的异或和为 \(V/4\),直接暴力记搜即可。
int c[4] = {0, 1, 3, 0};
struct node{
int x, y, v;
bool operator<(const node o)const{
if(x != o.x)return x < o.x;
if(y != o.y)return y < o.y;
return v < o.v;
}
};
map<node,int>h;
int calc(int l,int r,int v){
if(!v)return (min(l, r) + 1) % P;
if(!l && !r)return 0;
node cur{l, r, v};
if(h.count(cur))return h[cur];
int sum = 0;
rep(x, 0, 1){
int y = (v ^ x) & 1;
if(x > l || y > r)continue;
ad(sum, calc((l - x) / 2, (r - y) / 2, v / 2));
}
return h[cur] = sum;
}
int ask(int l,int r,int v){
if(l < 0)return 0;
int ans = 0;
rep(i, 0, 3)rep(j, 0, 3){
int w = v ^ c[i] ^ c[j];
if(i > l || j > r)continue;
int p = (l - i) / 4, q = (r - j) / 4;
if(w % 4)continue;
if(i & 1){
if(j & 1){
if(!w)ad(ans, ((p + 1) % P) * ((q + 1) % P) % P);
}
else{
if(w / 4 <= q)ad(ans, (p + 1) % P);
}
}
else{
if(j & 1){
if(w / 4 <= p)ad(ans, (q + 1) % P);
}
else{
h.clear();
ad(ans, calc(p, q, w / 4));
}
}
}
if(!v)su(ans, min(l, r) + 1);
return ans;
}
int l, r, v;
signed main() {
read(l), read(r), read(v), l --;
int ans = ((ask(r, r, v) - 2 * ask(l - 1, r, v) + ask(l - 1, l - 1, v)) % P + P) % P;
cout << ans * ((P + 1) / 2) % P << endl;
return 0;
}
标签:XOR,cur,4x,int,题解,ARC133D,sum,return,bmod 来源: https://www.cnblogs.com/7KByte/p/15861283.html