CF878D Magic Breeding
不妨考虑一种特殊情况,权值为 如何求解?
此时 个数可以表示为 位二进制数,
注意到位是独立的,将每一位拆开后最多只会有 种不同的情况。
而 , 那么我们可以忽略列数而关心列的状态
那么记 表示第 个元素,前 个元素构成的列的状态为 时该位的值。
那么, 操作相当于或, 操作相当于与。
对于一般情况,注意到答案只会是原来的 个元素的权值之一,枚举这个权值 ,然后 的位置视为 , 的位置视为 ,就转化为 的情况。
可以通过 bitset
优化做到
#include <bits/stdc++.h>
using namespace std;
#define pii pair< int , int >
#define fi first
#define sc second
#define mp make_pair
const int MAXN = 1e5 , MAXK = 12;
int n , k , q , a[ MAXK + 5 ][ MAXN + 5 ];
vector< pii > val[ MAXN + 5 ];
bitset< 1 << MAXK > f[ MAXN + 20 ];
int main( ) {
scanf("%d %d %d",&n,&k,&q);
for( int i = 1 ; i <= k ; i ++ ) {
for( int j = 1 ; j <= n ; j ++ )
scanf("%d",&a[ i ][ j ]) , val[ j ].push_back( mp( a[ i ][ j ] , i - 1 ) );
for( int S = 0 ; S < 1 << k ; S ++ ) f[ i ][ S ] = ( S >> i - 1 ) & 1;
}
for( int j = 1 ; j <= n ; j ++ ) sort( val[ j ].begin() , val[ j ].end() );
int cnt = k;
for( int i = 1 , t , x , y ; i <= q ; i ++ ) {
scanf("%d %d %d",&t,&x,&y);
if( t == 1 ) f[ ++ cnt ] = f[ x ] | f[ y ];
if( t == 2 ) f[ ++ cnt ] = f[ x ] & f[ y ];
if( t == 3 ) {
int ans = 0;
for( int j = k - 1 , cur = 0 ; j >= 0 ; j -- ) {
cur |= 1 << val[ y ][ j ].sc;
if( f[ x ][ cur ] ) { ans = val[ y ][ j ].fi; break; }
}
printf("%d\n", ans );
}
}
return 0;
}
分类:
其他-trick
, 数据结构-bitset 优化
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现