题目
题目描述
小 D 在玩一款角色扮演游戏,通过前期的打怪,他现在得到了 kk 个不同的装备。
众所周知,角色扮演游戏中常常有复杂的人物属性,在这款游戏中,小 D 一共有 nn 种不同的属性,而每件装备都会都对这 nn 种属性有不同buff效果。
今天,小 D 走到一家铁匠铺里去合成装备。他每次可以将两个装备合成一个标号为 m+1m+1(mm 为当前装备个数)的新装备(原来的两个装备不会消失),但是由于小 D 锻造技术不高,所以合成有可能成功也有可能失败。如果合成成功,他会得到一个新装备,而新装备的各项属性的buff是两个装备对应属性的maxmax,而如果合成失败,他会得到一个新装备,新装备的各项属性的buff是两个装备对应属性的minmin。
现在小 D 现在有 qq 个操作,每次操作如下:
11 xx yy : 表示小 D 将第 xx 和第 yy 个装备合成了,并且合成成功。
22 xx yy : 表示小 D 将第 xx 和第 yy 个装备合成了,并且合成失败。
33 xx yy : 小 D 想知道第 xx 装备的第 yy 项属性的buff是多少。
输入格式
第一行三个整数 n,k,qn,k,q。
接下来 kk 行,每行 nn 个整数 aijaij,表示初始第 ii 件物品的第 jj 种属性的buff。
接下来 qq 行,每行三个整数描述一个操作。
输出格式
对于每一个 33 操作,输出一行一个整数表示答案。
样例输入
3 3 7
1 6 9
3 5 1
8 7 2
1 1 2
2 4 3
2 5 1
1 6 6
3 5 2
3 4 3
3 7 1
样例输出
6
9
1
数据范围
对于 20%20% 的数据,满足 n≤100n≤100。
对于另外 20%20% 的数据,合成不会失败(即没有 22 操作)。
对于 100%100% 的数据,满足 1≤n,q≤105,k≤12,1≤aij≤1091≤n,q≤105,k≤12,1≤aij≤109。
思路
考虑每一件装备维护一个集合S,里面的元素是A,A是一个2k的状态
那么对于每一个装备的属性满足
不难发现,如果两个装备取max,就是两个装备的并集,反之取min就是两个装备的交集,用bitset轻松解决
查询时只需要按照属性枚举bitset里面的状态就行了
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+77;
int n,k,q,a[15][N],yjy;
bitset<8192> f[N];
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]);
for(int i=1; i<=k; i++) for(int j=0; j<(1<<k); j++) f[i][j]=(j>>(i-1)&1);
yjy=k;
while(q--)
{
int op,x,y;
scanf("%d%d%d",&op,&x,&y);
if(op==1) f[++yjy]=f[x]|f[y];
else if(op==2) f[++yjy]=f[x]&f[y];
else
{
int ans=0;
for(int i=1; i<=k; i++)
{
int s=0;
for(int j=1; j<=k; j++) if(a[j][y]>=a[i][y]) s|=1<<(j-1);
if(f[x][s]) ans=max(ans,a[i][y]);
}
printf("%d\n",ans);
}
}
}