目前是 76pts,感觉是单 log 的啊,应该不至于这么低吧,求看看是不是假成双 log 的了。
#include<bits/stdc++.h>
#define ls(k) k << 1
#define rs(k) k << 1 | 1
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
#define Add(x,y) (x+y>=mod)?(x+y-mod):(x+y)
#define lowbit(x) x&(-x)
#define pi pair<ll,ll>
#define pii pair<ll,pair<ll,ll>>
#define iip pair<pair<ll,ll>,ll>
#define ppii pair<pair<ll,ll>,pair<ll,ll>>
#define fi first
#define se second
#define full(l,r,x) for(auto it=l;it!=r;it++) (*it)=x
#define Full(a) memset(a,0,sizeof(a))
#define open(s1,s2) freopen(s1,"r",stdin),freopen(s2,"w",stdout);
#define For(i,l,r) for(register int i=l;i<=r;i++)
#define _For(i,l,r) for(register int i=r;i>=l;i--)
using namespace std;
using namespace __gnu_pbds;
typedef double db;
typedef unsigned long long ull;
typedef long long ll;
bool Begin;
const int N = 2e5 + 10, M = 19;
inline ll read(){
register ll x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-')
f=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=(x<<1)+(x<<3)+(c^48);
c=getchar();
}
return x*f;
}
inline void write(register ll x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)
write(x/10);
putchar(x%10+'0');
}
inline char get(){
char c;
while(1){
c = getchar();
if(c == '0' || c == '1')
break;
}
return c;
}
struct Node{
int l, r;
int dep, id;
ll ans, sum;
}X[N << 2];
struct Ques{
bool op;
int x;
};
int T, K, n, m, k, base = 1;
int _a[N], a[N], c[N], id[N], len[M], _X[4];
ll ans;
ll Ans[N];
vector<Ques> Q;
bool f[M][N];
inline void pushup(int k){
X[k].sum = X[ls(k)].sum + X[rs(k)].sum;
if(X[k].r > n)
return ;
if(f[X[k].dep][X[k].id]){
if(a[X[rs(k)].ans] >= X[k].dep)
X[k].ans = X[rs(k)].ans;
else
X[k].ans = X[ls(k)].ans;
}
else{
if(a[X[ls(k)].ans] >= X[k].dep)
X[k].ans = X[ls(k)].ans;
else
X[k].ans = X[rs(k)].ans;
}
}
inline void build(int k, int l, int r, int d){
X[k].ans = 0;
X[k].l = l, X[k].r = r;
X[k].dep = d, X[k].id = ++len[d];
if(l == r){
if(l <= n)
X[k].ans = l;
else
X[k].ans = 0;
X[k].sum = l;
return ;
}
int mid = (l + r) >> 1;
build(ls(k), l, mid, d - 1);
build(rs(k), mid + 1, r, d - 1);
pushup(k);
if(X[k].id == 1){
Ans[X[k].r] = X[k].ans;
id[X[k].r] = k;
}
}
int tim = 0;
inline pair<int, ll> dfs(int k, int x){
++tim;
if(X[k].r <= x)
return {X[k].ans, 0};
if(X[k].l > x)
return {0, X[k].sum};
int mid = (X[k].l + X[k].r) >> 1;
auto L = dfs(ls(k), x);
auto R = dfs(rs(k), x);
if(f[X[k].dep][X[k].id]){
if(L.se){
if(x > mid)
Q.push_back({1, X[k].dep - 1});
return {0, L.se + R.se};
}
if(R.se){
if(x > mid)
Q.push_back({1, X[k].dep - 1});
Q.push_back({0, L.fi});
}
else if(a[R.fi] < X[k].dep){
Q.push_back({1, K});
return L;
}
return R;
}
else{
if(L.se){
Q.push_back({1, X[k].dep - 1});
return {0, L.se + R.se};
}
if(a[L.fi] >= X[k].dep){
if(x > mid)
Q.push_back({1, K});
return L;
}
return R;
}
}
inline ll work(int x){
tim = 0;
Q.clear();
int base = 1;
while(base < x)
base <<= 1;
auto it = dfs(id[base], x);
ll ans = it.fi + it.se;
int len = Q.size(), Max = -1;
for(int i = len - 1; i >= 0; --i){
if(Q[i].op == 1)
Max = max(Max, Q[i].x);
else{
if(Max < a[Q[i].x])
ans += Q[i].x;
}
}
return ans;
}
inline void solve(){
ans = 0;
for(int i = 0; i <= k; ++i)
len[i] = 0;
for(int i = 0; i < 4; ++i)
_X[i] = read();
for(int i = 2; i <= n; ++i)
Ans[i] = -1;
for(int i = 1; i <= n; ++i){
a[i] = _a[i] ^ _X[i % 4];
a[i] = min(a[i], k);
}
build(1, 1, (1 << k), k);
for(int i = 1; i <= m; ++i){
if(Ans[c[i]] != -1)
ans ^= Ans[c[i]] * i;
else
ans ^= (Ans[c[i]] = work(c[i])) * i;
}
write(ans);
putchar('\n');
}
bool End;
int main(){
// open("A.in", "A.out");
Ans[1] = 1;
n = read(), m = read();
while(base < n){
++k;
base <<= 1;
}
K = k;
for(int i = 1; i <= n; ++i)
_a[i] = read();
for(int i = 1; i <= m; ++i)
c[i] = read();
for(int i = 1; i <= k; ++i)
for(int j = 1; j <= (1 << (k - i)); ++j)
f[i][j] = get() - '0';
T = read();
while(T--)
solve();
cerr<<'\n'<<abs(&Begin-&End)/1048576<<"MB";
return 0;
}