列表

详情


NC15048. 假的线段树

描述

给你一个长为n的序列a,有m次操作

1.把区间[l,r]内所有x变成y

2.查询区间[l,r]内第k小值

输入描述

第一行两个数n,m
第二行n个数表示序列a
后面m行
1 l r x y :把区间[l,r]中所有x变成y
2 l r k :查询区间[l,r]中的第k小值

输出描述

对于每个询问,输出一个数表示答案

示例1

输入:

3 3
2 3 3
2 1 3 1
1 1 3 3 1
2 1 3 2

输出:

2
1

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 12ms, 内存消耗: 504K, 提交时间: 2020-05-08 11:50:37

#include<bits/stdc++.h>
using namespace std;

int main()
{
    int i,l,r,x,y,op,n,m,a[1005],b[1005];
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)scanf("%d",&a[i]);
    while(m--)
    {
    	scanf("%d%d%d",&op,&l,&r);
    	if(op==1)
    	{
    		scanf("%d%d",&x,&y);
    		for(i=l;i<=r;i++)if(a[i]==x)a[i]=y;
		}
		else
		{
			scanf("%d",&x);
			for(i=l;i<=r;i++)b[i-l+1]=a[i];
			sort(b+1,b+r-l+2);
			printf("%d\n",b[x]);
		}
	}
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 14ms, 内存消耗: 384K, 提交时间: 2018-01-26 19:19:54

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n,m;
	cin>>n>>m;
	int a[1001];
	for (int i=1;i<=n;i++)cin>>a[i];
	while(m--){
		int c,l,r,x,y;
		cin>>c;
		if (c==1){
			cin>>l>>r>>x>>y;
			for (int i=l;i<=r;i++)if (a[i]==x)a[i]=y;
		}
		else{
			cin>>l>>r>>x;
			int b[1001];
			memcpy(b,a+l,sizeof(int)*(r-l+1));
			sort(b,b+(r-l+1));
			cout<<b[x-1]<<endl;
		}
	}
}

Python3 解法, 执行用时: 106ms, 内存消耗: 6856K, 提交时间: 2021-06-12 15:43:28

n,m = map(int,input().split())
arr = list(map(int,input().split()))
for i in range(m):
    get = list(map(int,input().split()))
    if get[0] == 1:
        for j in range(get[1]-1,get[2]):
            if arr[j] == get[3]:
                arr[j] = get[4]
    else:
        copy = arr[get[1]-1:get[2]]
        copy.sort()
        print(copy[get[3]-1])

上一题