A 假的线段树
链接:https://www.nowcoder.com/acm/contest/59/A
来源:牛客网
题目描述
给你一个长为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
备注:
对于100%的数据,1 <= n, m , ai <= 1000
分析:
数据范围不大暴力,按照题目模拟,查找第k大值时,sort和nth_element都能过;
#include
#include
#include
using namespace std;
int a[2010], b[2010];
int main() {
int n, m;
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
}
while(m--) {
int op, L, R, x, y;
scanf("%d", &op);
if(op == 1) {
scanf("%d %d %d %d", &L, &R, &x, &y);
for(int i = L; i <= R; i++) {
if(a[i] == x) {
a[i] = y;
}
}
}
else {
scanf("%d %d %d", &L, &R, &x);
for(int i = L; i <= R; i++) {
b[i - L + 1] = a[i];
}
// sort(b + 1, b + R - L + 2);
nth_element(b + 1, b + x, b + R - L + 2);
printf("%d\n", b[x]);
}
}
return 0;
}
D 求距离
链接:https://www.nowcoder.com/acm/contest/59/D
来源:牛客网
题目描述
给你一个1 -> n的排列,现在有一次机会可以交换两个数的位置,求交换后最小值和最大值之间的最大距离是多少?
输入描述:
第一行一个数n,之后一行n个数表示这个排列
输出描述:
输出一行一个数表示答案
示例1
输入
5
4 5 1 3 2
输出
3
说明
把1和2交换后
序列为4 5 2 3 1
最大值5在数组的2位置,最小值1在数组的5位置距离为3
备注:
对于100%的数据,1 <= n <= 100
分析:
把最大值最小值的位置保存下来,固定一个,另一个放置左端或右端,枚举四个答案;
#include
#include
#include
using namespace std;
int main() {
int n, maxn, minn, k;
int maxn_id = 1, minn_id = 1;
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d", &k);
if(i == 1) {
maxn = k;
minn = k;
}
if(maxn < k) {
maxn = k;
maxn_id = i;
}
if(minn > k) {
minn = k;
minn_id = i;
}
}
int ans1 = minn_id - 1;
int ans2 = max(ans1, maxn_id - 1);
int ans3 = max(ans2, n - minn_id);
int ans4 = max(ans3, n - maxn_id);
printf("%d\n", ans4);
return 0;
}
E 求最值
链接:https://www.nowcoder.com/acm/contest/59/E
来源:牛客网
题目描述
给你一个长为n的序列a,定义 f(i,j)=(i−j)2+g(i,j)2 f ( i , j ) = ( i − j ) 2 + g ( i , j ) 2
g是这样的一个函数:
求最小的 f(i,j) f ( i , j ) 的值, i!=j i ! = j
输入描述:
第一行一个数n,之后一行n个数表示序列a
输出描述:
输出一行一个数表示答案
示例输入
4
1 0 0 -1
输出
1
备注:
对于100%的数据,2 <= n <= 100000 , |ai| <= 10000
分析:
我选择暴力1000项,数据水给过了。。。
题解是转化成平面最近点对,O(nlogn);
#include
#include
#include
using namespace std;
typedef long long LL;
const int MAXN = 1e5 + 10;
LL a[MAXN], sum[MAXN];
int main() {
int n;
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%lld", &a[i]);
sum[i] += sum[i - 1] + a[i];
}
LL cnt, ans = a[1] * a[1] + 1;
for(int i = 1; i <= n; i++) {
for(int j = max(i - 1000, 0); j < i; j++) {
if(abs(sum[i] - sum[j]) > 1e4) continue;
cnt = (i - j) * (i - j) + (sum[i] - sum[j]) * (sum[i] - sum[j]);
ans = min(ans, cnt);
}
}
printf("%lld\n", ans);
return 0;
}