专栏文章
题解:P7335 [JRKSJ R1] 异或
P7335题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @min2jmnq
- 此快照首次捕获于
- 2025/12/01 19:31 3 个月前
- 此快照最后确认于
- 2025/12/01 19:31 3 个月前
5pts:
直接爆搜。。
40pts:
发现可能可以 DP。记 为前 个数中选 个区间,则转移方程:
。(不选区间)
。(选区间)
时间复杂度 。
100pts:
我们定义一个区间是“无用的”,当且仅当存在另一个区间,使得这个区间比另一个区间长,且没有另一个区间异或和大。
我们将这些无用区间抛弃掉,剩下几个区间?考虑一个长度为 的区间,必然是有用的。长度为 的呢?因为数据随机,所以 异或 大于 的概率是 ,同理,一个长度为 的区间,是有用的概率为 。
所以在剔除无效区间后再 DP。调和级数 是 的,所以时间复杂度 。
CPP#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3009;
struct Node{
int l,r,w;
}s[N][N];
int n,k,V,x[N],num[N],mx[N][N];
ll f[N][2];
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++)
cin>>x[i],x[i]=x[i-1]^x[i];
for(int i=1;i<=n;i++)
for(int j=i-1,tmp=0;j>=0;j--)
tmp=max(tmp,x[i]^x[j]),mx[j][i]=max(mx[j][i-1],tmp);
for(int i=1;i<=n;i++){
s[i][1].l=s[i][1].r=0;
s[i][1].w=mx[0][i];
num[i]=1;
for(int j=1;j<i;j++)
if(mx[j][i]==mx[j-1][i]) s[i][num[i]].r++;
else{
s[i][++num[i]].l=j;
s[i][num[i]].r=j;
s[i][num[i]].w=mx[j][i];
}
}
for(ll j=1;j<=k;j++)
for(ll i=1;i<=n;i++){
f[i][j%2]=0;
for(ll x=1;x<=num[i];x++)
f[i][j%2]=max(f[i][j%2],f[s[i][x].r][(j%2)^1]+s[i][x].w);
}
cout<<f[n][k%2]<<endl;
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...