D2. Xor-Subsequence (hard version)
D2. Xor-Subsequence (hard version)
昨天cf的E题,挺好的一个DP优化问题。
暴力的DP就是设dp[i]表示以i结尾的最长长度。转移时枚举之前的所有j,复杂度O(n^2)。
考虑怎么优化,优化往往都是从转移条件上做文章的,我们考虑当前i的dp值怎么计算,
是所有max(f[j]+1),而且这些j满足aixorj<ajxori。
左边小于右边,又与异或有关,所以考虑二进制,在二进制下,一定满足一个k,使得从高到底数,前k-1位两者都相等,第k位右边为1,左边为0.那么倘若我们只考虑这前k-1位的话,可以发现aixorj=ajxori,则aixorjxorajxori=0.可得aixori=ajxorj。(终于将i和j分开了...因为在dp优化问题中,我们尽量使得j和i没关系,这样的话方便我们进行操作。)至于第k位,由于我们知道i和ai的信息,所以j和aj在这一位上是0还是1就确定了。至此我们考虑用什么样的一个数据结构去优化这个过程。
tire树,因为我们看到aixori和ajxorj相等,tire树正好可以实现这个操作,并且我们在插入的过程中完全可以维护i和a[i]这一位上位0还是1的信息。
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10,M=1e7+10;
int T,n,a[N],tire[M][2],f[M][2][2],dp[N],tot;
//f[x][0/1][0/1]表示x及其之前的都相等,x下一位开始,i为0/1,a[i]为0/1的dp最大值.
inline int query(int id,int val)
{
int p=1,ans=0;
for(int i=30;i>=0;--i)
{
int c2=(val&(1<<i))?0:1,c1=(id&(1<<i))?1:0;
ans=max(ans,f[p][c2][c1]);
int ch=((id^val)&(1<<i))?1:0;
if(!tire[p][ch]) break;
p=tire[p][ch];
}
return ans;
}
inline void insert(int id,int val)
{
int p=1;
for(int i=30;i>=0;--i)
{
int c2=(val&(1<<i))?1:0,c1=(id&(1<<i))?1:0;
f[p][c1][c2]=max(f[p][c1][c2],dp[id]);
int ch=((id^val)&(1<<i))?1:0;
if(!tire[p][ch]) tire[p][ch]=++tot;
p=tire[p][ch];
}
}
inline void solve()
{
cin>>n;
for(int i=0;i<n;++i) cin>>a[i];
tot=1;
int ans=0;
for(int i=0;i<n;++i)
{
int temp=query(i,a[i]);
dp[i]=temp+1;
insert(i,a[i]);
ans=max(ans,dp[i]);
}
cout<<ans<<endl;
for(int i=1;i<=tot;++i)
for(int j=0;j<2;++j)
{
tire[i][j]=0;
for(int k=0;k<2;++k) f[i][j][k]=0;
}
}
int main()
{
// freopen("1.in","r",stdin);
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>T;
while(T--) solve();
return 0;
}
标签:
codeforces
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
2021-08-19 ICPC Mid-Central USA Region 2019 题解
2021-08-19 2021牛客暑期多校训练营10