题解:P10690 Fotile 模拟赛 L
WilliamFranklin · · 题解
不懂为啥都可持久化 Trie,甚至有的人还用区间 dp 过了。
这里讲一种比区间 dp 更好写,且跑的更快的做法,时间复杂度也为
代码压一压 596B。
Solution
先求前缀异或和是自然的。
考虑对于每个
然后查询的时候就是
比区间 dp 快了 300ms。
:::success[AC Code]
#include <bits/stdc++.h>
using namespace std;
#define x first
#define y second
#define mp(Tx, Ty) make_pair(Tx, Ty)
#define For(Ti, Ta, Tb) for(auto Ti = (Ta); Ti <= (Tb); Ti++)
#define Dec(Ti, Ta, Tb) for(auto Ti = (Ta); Ti >= (Tb); Ti--)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define range(Tx) begin(Tx),end(Tx)
const int N = 12005;
int f[N * N / 2];
int n, m, a[N];
int pre[N];
int get(int x, int y) {
if (x == y) return 0;
return x * (x - 1) / 2 + y + 1;
}
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
cin >> n >> m;
For(i ,1, n) cin >> a[i];
For(i, 1,n) pre[i] = pre[i - 1] ^ a[i];
For(i ,1, n) Dec(j, i - 1, 0) f[get(i, j)] = max(f[get(i, j + 1)], pre[i] ^ pre[j]);
int lastans = 0;
while (m--) {
int x, y;
cin >> x >> y;
x = (1ll * x + lastans) % n + 1;
y = (1ll * y + lastans) % n + 1;
if (x > y) swap(x, y);
lastans = 0;
For(i, x, y) lastans = max(lastans, f[get(i, x - 1)]);
cout << lastans << '\n';
}
return 0;
}
:::
这里再给个压行的。
:::success[AC Code]
#include <iostream>
using namespace std;
#define For(Ti,Ta,Tb) for(auto Ti=(Ta);Ti<=(Tb);Ti++)
#define Dec(Ti,Ta,Tb) for(auto Ti=(Ta);Ti>=(Tb);Ti--)
const int N=12005;
int n,m,a[N],f[N*N/2],pre[N],x,y,lastans;
int get(int x,int y){return x*(x-1)/2+y+1;}
int main(){
cin>>n>>m;
For(i,1,n)cin>>a[i];
For(i,1,n)pre[i]=pre[i-1]^a[i];
For(i,1,n)Dec(j,i-1,0)f[get(i,j)]=max(f[get(i,j+1)],pre[i]^pre[j]);
while(m--){
cin>>x>>y;
x=(1ll*x+lastans)%n+1,y=(1ll*y+lastans)%n+1;
if(x>y)swap(x,y);
lastans=0;
For(i,x,y)lastans=max(lastans,f[get(i,x-1)]);
cout<<lastans<<'\n';
}
return 0;
}
:::