题解:P14359 [CSP-J 2025] 异或和 / xor(民间数据)
分享一个时间空间复杂度都是
这题很显然是 dp。令
考虑状态转移。很显然有当区间
这个时候可以写出一个比较暴力的代码(这里使用了类似前缀和的前缀异或和,跟前缀和是一码事)。
#include <bits/stdc++.h>
#define int long long
using namespace std;
int a[500005];
int dp[500005];
int prexor[500005];
signed main(){
int n,m;
cin>>n>>m;
for (int i=1;i<=n;i++){
cin>>a[i];
prexor[i]=a[i]^prexor[i-1];
}
for (int i=1;i<=n;i++){
for (int j=1;j<=i;j++) dp[i]=max(dp[i],dp[j-1]+(int)((prexor[i]^prexor[j-1])==m));
}
cout<<dp[n];
}
但很显然时间复杂度太高了,那怎么优化呢?
观察到一个废话:
符合这个的
最终代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
int a[500005];
int dp[500005];
int prexor[500005];
unordered_map<int,int> mp;
signed main(){
mp[0]=0;
int n,m;
cin>>n>>m;
for (int i=1;i<=n;i++){
cin>>a[i];
prexor[i]=a[i]^prexor[i-1];
}
for (int i=1;i<=n;i++){
dp[i]=dp[i-1];
int want=m^prexor[i];
if (mp.count(want)) dp[i]=max(dp[i],dp[mp[want]]+1);
mp[prexor[i]]=i;
}
cout<<dp[n];
}