CodeForces - 878D 递归(搜索)

开始有k个生物,有n个属性
支持3种操作:
1.将两个生物合并成一个新的生物,所有属性值为原来的较大值
2.将两个生物合并成一个新的生物,所有属性值为原来的较小值
3.询问i生物的第j个属性值

n<=1e5 k<=12 q<=1e5

Input

三个数 n k q分别表示属性数,生物数以及操作数
之后k行每行n个正整数,表示生物属性(属于[1,1e9])
之后q行,每行3个数对应一个操作

Output

对于每次询问输出一行表示答案

Example

Input1
3 2 4
1000000000 1000000000 1
1 1000000000 1000000000
1 1 2
2 1 2
3 3 2
3 4 2
Input2
1 3 2
3
2
1
2 1 3
3 4 1

Output1
1000000000
1000000000
Output2
1

Note

对于第一个样例 
第三个生物属性为1000000000 1000000000 1000000000 
第四个生物属性为1 1000000000 1

本题不能打表,内存会炸,只能递归;

一开始递归出了毛病WA,后来想明白了

代码如下:

#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define inf 0x3f3f3f3f
#define N 100010
using namespace std;
int n,k,q;
int v[20][N];
struct A{
    int a,b,c;
}x[N];
int dfs(int a,int c){
    if(a<=k)return v[a][c];
    if(x[a].a==1){
        return max(dfs(x[a].b,c),dfs(x[a].c,c));
    }else{
        return min(dfs(x[a].b,c),dfs(x[a].c,c));
    }
}
int main(){
    while(scanf("%d %d %d",&n,&k,&q)!=EOF){
        int a,b,c;
        for(int i=1;i<=k;i++){
            for(int j=1;j<=n;j++){
                scanf("%d",&a);
                v[i][j]=a;
            }
        }
        int t=k+1;
        while(q--){
            scanf("%d %d %d",&a,&b,&c);
            if(a==3){
                printf("%d\n",dfs(b,c));
            }else{
                x[t].a=a;x[t].b=b;x[t++].c=c;
            }
        }
    }
    return 0;
}

 

你可能感兴趣的:(递归)