单 log 76pts 被卡常求调
查看原帖
单 log 76pts 被卡常求调
979266
Genius_Star楼主2024/10/28 23:31

目前是 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;
}
2024/10/28 23:31
加载中...