bitset 求解高维偏序
菜,题简单,trick 蠢,求别骂。
记录今天做题的时候遇到的一个小 trick。
先看一道题:P3810 【模板】三维偏序(陌上花开)。
平凡的三维偏序板子,相信大家都会用 CDQ/树套树/K-D tree 之类的优秀做法秒了吧!
然后看这个题:求五维偏序,
我会套三层 CDQ 做到
然后看这个题:CF1826E. Walk the Runway。
题意有点复杂,但是就是需要求
显然 CDQ 并不可取,如果直接暴力也是 我不会)。怎么办?这里介绍一种使用 bitset 的简单做法。
有一个
还可以优化吗?
考虑这道题:
空间爆了,怎么办?考虑分块优化空间。我们对于每一维进行值域上的分块,块长
这样做的话时间复杂度依旧是
附一个 CF1826E 的代码。
点击查看代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll inf=1e18;
inline int read(){
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
struct edge{
int v,nxt;
}e[25000005];
int tot,head[5005],deg[5005];
void add(int u,int v){
e[++tot]=(edge){v,head[u]},head[u]=tot,deg[v]++;
}
int n,m,b[5005],p[5005];ll a[5005],f[5005];
int cmp(int x,int y){
return b[x]<b[y];
}
bitset<5005>res[5005];
void solve(){
m=read(),n=read();
for(int i=1;i<=n;i++)a[i]=read();
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)if(i!=j)res[i][j]=1;
for(int j=1;j<=m;j++){
for(int i=1;i<=n;i++)b[i]=read(),p[i]=i;
sort(p+1,p+n+1,cmp);bitset<5005>tmp;
for(int i=1;i<=n;i++){
int pos=i;while(pos<=n&&b[p[pos]]==b[p[i]])res[p[pos]]&=tmp,pos++;
pos--;for(int k=i;k<=pos;k++)tmp[p[k]]=1;
i=pos;
}
}
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)if(res[i][j])add(i,j);
queue<int>q;for(int i=1;i<=n;i++)if(!deg[i])q.push(i),f[i]=a[i];
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].v;f[v]=max(f[v],f[u]+a[v]);
if((--deg[v])==0)q.push(v);
}
}
ll ans=0;
for(int i=1;i<=n;i++)ans=max(ans,f[i]);
printf("%lld\n",ans);
}
signed main(){
int T=1;
while(T--){
solve();
}
return 0;
}
reference:几道很Interesting的偏序问题 - yyb,bitset 求解高维偏序。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通