码迷,mamicode.com
首页 > 其他好文 > 详细

[多校练习] 成都七中数据结构 Challenge 系列解题报告

时间:2021-03-16 11:41:02      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:namespace   插入   algorithm   main   操作   name   解答   end   include   

Challenge 0

给一个长为 \(n\) 的数列,有 \(M\) 次操作 \((1\le n, m \le 10^5)\),每次操作是以下两种之一:

  • 修改数列中的一个数
  • 求数列中某位置的值

解答:数组模拟即可。

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 5;
int a[maxn], n, m;
int main() {
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
	while(m --) {
		char cmd;
		cin >> cmd;
		if(cmd == ‘Q‘) {
			int x;
			cin >> x;
			cout << a[x] << endl;
		} else {
			int x, d;
			scanf("%d%d", &x, &d);
			a[x] = d;
		}
	}
}

Challenge 1

给一个长为 \(n\) 的数列,有 \(M\) 次操作 \((1\le n, m \le 10^5)\),每次操作是以下两种之一:

  • 修改数列中的一个数
  • 求数列中某位置在某次操作后的值

解答:我们发现,数据范围是允许均摊根号的算法的。我们可以对每个位置建立链表,修改时向该位置插入新节点并保存时间,查询时沿着链表找到第一个时间戳小于 \(k\) 的数字。但是发现动态分配内存的指针链表十分难写,于是用 vector 代替。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 1e5 + 5;
struct node {
	int tim, val;
} nul;
vector<node> a[maxn];
int b[maxn];
int main() {
	int n, m;
	nul.tim = 0, nul.val = 0;
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; i ++)  a[i].push_back(nul);
	for(int i = 1, x; i <= n; i ++) {
		scanf("%d", &x);
		node tmp;
		tmp.tim = 0, tmp.val = x;
		a[i].push_back(tmp);
		b[i] ++;
	} for(int i = 1; i <= m; i ++) {
		char cmd;
		cin >> cmd;
		if(cmd == ‘Q‘) {
			int x, v, ans;
			cin >> x >> v;
			int now = 0;
			while(a[x][now].tim <= v && now <= b[x]) {
				ans = a[x][now].val;
				now ++;
			} printf("%d\n", ans);
		} else {
			int x, d;
			cin >> x >> d;
			node tmp;
			tmp.tim = i, tmp.val = d;
			a[x].push_back(tmp);
			b[x] ++; 
		}
	}
}

[多校练习] 成都七中数据结构 Challenge 系列解题报告

标签:namespace   插入   algorithm   main   操作   name   解答   end   include   

原文地址:https://www.cnblogs.com/Inversentropir-36/p/14531164.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!