题面传送门

很容易发现一件事情,那就是数组的每一位都是独立的,但由于这题数组长度 \(n\) 很大,我们不能每次修改都枚举每一位更新其对答案的贡献,这样复杂度必炸无疑。但是这题有个显然的突破口,那就是 \(k\) 的取值范围很小,最高只有 \(12\),也就是说每一位的取值最多只有 \(12\) 种可能,我们考虑以此为突破口,设计一个与这 \(k\) 个数的具体取值无关的状态。

首先我们知道每一位是独立的,故我们可以把每一位拆开来考虑,于是问题由二维变成一维:给定 \(k\) 个数 \(a_1,a_2,\dots,a_k\),\(q\) 次操作,每次操作给定两个数 \(i,j\),有两种类型,要么新建一个数 \(a_n=\max(a_i,a_j)\),要么新建一个数 \(a_n=\min(a_i,a_j)\)。

我们先来看一个弱化版本,那就是 \(\forall a_i\in [0,1]\),我们设计一个状态 \(f_{i,S}\),\(f_{i,S}=1\) 表示 \(\forall j\in S,a_j=1\Rightarrow a_i=1\),也就是说如果 \(S\) 中的元素都为 \(1\) 那么 \(a_i\) 就一定为 \(1\),否则不能确定 \(a_i\) 究竟是 \(1\) 还是 \(0\),显然最初对于 \(i\in[1,k]\),满足 \(i\in S\) 的 \(f_{i,S}\) 都为 \(1\),其余的 \(f_{i,S}\) 都为 \(0\)。

我们考虑新建一个 \(a_n=\max(a_i,a_j)\) 会造成什么样的影响,对于集合 \(S\),如果 \(f_{i,S}=1\lor f_{j,S}=1\),那么 \(a_i,a_j\) 中一定至少有一个为 \(1\),故 \(a_n=\max(a_i,a_j)\) 一定为 \(1\),故 \(f_{n,S}=1\)。反之,\(f_{i,S}=f_{j,S}=0\),我们就不能确定 \(a_i,a_j\) 的值,也就是说最坏情况下会出现 \(a_i=a_j=0\) 的情况,此时 \(a_n=0\),故 \(f_{n,S}=0\)。故我们有 \(f_n=f_i\lor f_j\)。同理我们也可将取 \(\min\) 的情况与 \(\land\) 联系在一起。至于查询……比方说我们要查询第 \(x\) 个数组第 \(y\) 列的数,我们记 \(T=\{i|a_{i,y}=1,i\in [1,k]\}\),如果 \(f_{x,T}=1\),根据 \(f\) 数组的定义可知 \(a_{x,y}=1\),反之,根据 \(f\) 数组的定义知在剩下数乱填的情况下,有可能出现 \(a_x=0\) 的情况,显然在“\(T\) 之外的数乱填”的情况下,让 \(a_x\) 值最小的填法是其它数全填 \(0\),而我们有 \(\forall i\notin T,a_{i,y}=0\),故 \(a_x=0\)。也就是说我们只需输出 \(f_{x,T}\) 即可,复杂度 \(q2^k+2^k\),使用 bitset 即可优化到 \(\dfrac{q2^k}{w}+k2^k\)

现在我们考虑将更一般的情况规约到特殊情况,由于每一位是独立的,我们还是将目光聚焦到某一特定的列(假设为第 \(i\) 列)上,对于初始 \(k\) 个数组第 \(i\) 列上的数我们将其从大到小排个序,设排好序的数组为 \(x_{1},x_2,\dots,x_k\),我们对于每个 \(a_{t,i}\)(包括新建的数组)新建 \(k\) 个 0/1 变量 \(b_{t,1,i},b_{t,2,i},\dots,b_{t,k,i}\),其中 \(b_{t,j,i}\) 为 \(1\) 表示 \(a_{t,i}\ge x_j\),反之 \(a_{t,i}<x_j\),查询就从 \(1\) 枚举到 \(k\) 直到遇到第一个 \(b_{x,i,y}=1\) 并输出 \(x_i\) 即可。显然这个小小的修改只不过是将数组长度由 \(n\) 变成了 \(nk\),在弱化版本中我们 \(f\) 数组的定义即求解方法照样使用,复杂度 \(\dfrac{q2^k}{w}+k^22^k\),有点脑子就可以优化到 \(q2^k+k2^k\)。

btw 为啥这么神仙的思维题现场那么多人 AC 啊,感觉这些 LGM 都不是人(

#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fz(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define ffe(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define ppb pop_back
#define mp make_pair
template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
typedef pair<int,int> pii;
typedef long long ll;
namespace fastio{
#define FILE_SIZE 1<<23
char rbuf[FILE_SIZE],*p1=rbuf,*p2=rbuf,wbuf[FILE_SIZE],*p3=wbuf;
inline char getc(){return p1==p2&&(p2=(p1=rbuf)+fread(rbuf,1,FILE_SIZE,stdin),p1==p2)?-1:*p1++;}
inline void putc(char x){(*p3++=x);}
template<typename T> void read(T &x){
x=0;char c=getchar();T neg=0;
while(!isdigit(c)) neg|=!(c^'-'),c=getchar();
while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(neg) x=(~x)+1;
}
template<typename T> void recursive_print(T x){if(!x) return;recursive_print(x/10);putc(x%10^48);}
template<typename T> void print(T x){if(!x) putc('0');if(x<0) putc('-'),x=~x+1;recursive_print(x);}
void print_final(){fwrite(wbuf,1,p3-wbuf,stdout);}
}
const int MAXK=12;
const int MAXS=1<<MAXK;
const int MAXN=1e5;
int n,k,qu,cnt,a[MAXK+3][MAXN+5];
bitset<MAXS+4> f[MAXN+MAXK+3];
pii ord[MAXN+5][MAXK+3];
bool cmp(pii x,pii y){return a[x.fi][x.se]>a[y.fi][y.se];}
int main(){
scanf("%d%d%d",&n,&k,&qu);cnt=k;
for(int i=1;i<=k;i++) for(int j=1;j<=n;j++) scanf("%d",&a[i][j]);
for(int j=1;j<=n;j++) for(int i=1;i<=k;i++) ord[j][i]=mp(i,j);
for(int j=1;j<=n;j++) sort(ord[j]+1,ord[j]+k+1,cmp);
for(int i=1;i<=k;i++) for(int j=0;j<(1<<k);j++) if(j>>i-1&1) f[i][j]=1;
while(qu--){
int opt,x,y;scanf("%d%d%d",&opt,&x,&y);
if(opt==1) f[++cnt]=f[x]|f[y];
else if(opt==2) f[++cnt]=f[x]&f[y];
else{
int msk=0;
for(int i=1;i<=k;i++){
msk|=1<<ord[y][i].fi-1;
if(f[x][msk]){
printf("%d\n",a[ord[y][i].fi][y]);
break;
}
}
}
}
return 0;
}

Codeforces 878D - Magic Breeding(bitset,思维题)的更多相关文章

  1. 【CF878D】Magic Breeding bitset

    [CF878D]Magic Breeding 题意:有k个物品,每个物品有n项属性值,第i个人的第j个属性值为aij,有q个操作: 1 x y 用x和y合成一个新的物品,新物品的编号是++k,新物品的 ...

  2. CF878D D. Magic Breeding bitset

    D. Magic Breeding time limit per test 4 seconds memory limit per test 1024 megabytes input standard ...

  3. C. Nice Garland Codeforces Round #535 (Div. 3) 思维题

    C. Nice Garland time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...

  4. Codeforces 515C 题解(贪心+数论)(思维题)

    题面 传送门:http://codeforces.com/problemset/problem/515/C Drazil is playing a math game with Varda. Let’ ...

  5. Codeforces 1188B - Count Pairs(思维题)

    Codeforces 题面传送门 & 洛谷题面传送门 虽说是一个 D1B,但还是想了我足足 20min,所以还是写篇题解罢( 首先注意到这个式子里涉及两个参数,如果我们选择固定一个并动态维护另 ...

  6. Codeforces 1365G - Secure Password(思维题)

    Codeforces 题面传送门 & 洛谷题面传送门 首先考虑一个询问 \(20\) 次的方案,考虑每一位,一遍询问求出下标的这一位上为 \(0\) 的位置上值的 bitwise or,再一遍 ...

  7. Codeforces 1129E - Legendary Tree(思维题)

    Codeforces 题面传送门 & 洛谷题面传送门 考虑以 \(1\) 为根,记 \(siz_i\) 为 \(i\) 子树的大小,那么可以通过询问 \(S=\{2,3,\cdots,n\}, ...

  8. CodeForces - 427A (警察和罪犯 思维题)

    Police Recruits Time Limit: 1000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u Sub ...

  9. E. Magic Stones CF 思维题

    E. Magic Stones time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...

随机推荐

  1. vue 解决axios请求出现前端跨域问题

    vue 解决axios请求出现前端跨域问题 最近在写纯前端的vue项目的时候,碰到了axios请求本机的资源的时候,出现了访问报404的问题.这就让我很难受.查询了资料原来是跨域的问题. 在正常开发中 ...

  2. 【UE4 设计模式】组件模式 Components Pattern

    概述 描述 在单一实体跨越了多个领域时,为了保持领域之间相互解耦,可以将每部分代码放入各自的组件类中,将实体简化为组件的容器. 套路 参考 UE4中的 Componet 组件使用方式 使用场景 有一个 ...

  3. Java:并发笔记-04

    Java:并发笔记-04 说明:这是看了 bilibili 上 黑马程序员 的课程 java并发编程 后做的笔记 本章内容-3 线程状态转换 活跃性 Lock 3.10 重新理解线程状态转换 假设有线 ...

  4. activiti会签 多实例例子

    在实际的业务中,可能存在存在这么一种情况,当流程运行到某一个环节时,可能需要同时多个人的参与,才可以完成此环节.此时就可以用到activiti的多实例来解决此问题. 一.将一个节点设置成多实例的方法: ...

  5. 手写vue-router & 什么是Vue插件

    博文分享 这篇文章你可以学习到: 实现一个自己的vue-router 了解什么是Vue的插件 学习b站大佬后做的笔记整理和源码实现 1.1.3一步一步带你弄懂vue-router核心原理及实现哔哩哔哩 ...

  6. Codeforces Round #735 (Div. 2)

    这次的cf依旧掉分..... A题和B题在不懈死磕下瞎搞出来了,不过还是被C题卡住了... C. Mikasa 简述题意就是给定n和m,让n^0,n^1,n^2...,n^m,求着m+1个数中没有出现 ...

  7. VS2013快捷键及技巧 / 智能插件

    复制/剪切/删除整行代码 1)如果你想复制一整行代码,只需将光标移至该行,再使用组合键"Ctrl+C"来完成复制操作,而无需选择整行. 2)如果你想剪切一整行代码,只需将光标移至该 ...

  8. gitbook热更新时报错operation not permitted

    在使用gitbook写东西的时候,当文档内容有更新的时候,会自动更新内容到页面上,方便预览.但是,存在一个bug,就是会神奇的崩溃掉,出现如下的错误提示: Restart after change i ...

  9. makefile简单学习(一)

    第一层 显式规则 目标:依赖 [tab] 指令 伪目标:.PHONY: 递归规则 hello : hello.o gcc hello.o -o hello hello.o : hello.s gcc ...

  10. 【Python接口自动化测试】Postman使用简介

    下载地址: http://www.downza.cn/soft/205171.html 工具栏 New: 新建,可以新建Request请求,Collection请求集,环境等等 Import: 导入, ...