6.5 今日做题记录

Codeforces Round 950 (Div. 3)





题面:

Sofia had an array of n integers a1,a2,…,an. One day she got bored with it, so she decided to sequentially apply m

modification operations to it.

Each modification operation is described by a pair of numbers 〈cj,dj〉

and means that the element of the array with index cj should be assigned the value dj, i.e., perform the assignment acj=dj

. After applying all modification operations sequentially, Sofia discarded the resulting array.

Recently, you found an array of n

integers b1,b2,…,bn. You are interested in whether this array is Sofia's array. You know the values of the original array, as well as the values d1,d2,…,dm. The values c1,c2,…,cm

turned out to be lost.

Is there a sequence c1,c2,…,cm

such that the sequential application of modification operations 〈c1,d1,〉,〈c2,d2,〉,…,〈cm,dm〉 to the array a1,a2,…,an transforms it into the array b1,b2,…,bn?

索菲亚有一个由 n 个整数 a1,a2,…,an 组成的数组。有一天,她对这个数组感到厌倦,于是决定对它进行 m

次修改操作。

每个修改操作都由一对数字 〈cj,dj〉

来描述,这意味着数组中索引为 cj 的元素应赋值为 dj ,即执行赋值 acj=dj

。在依次执行了所有***修改操作后,索菲亚丢弃了得到的数组。

最近,你发现了一个由 n

个整数组成的数组 b1,b2,…,bn 。你想知道这个数组是否是索菲亚的数组。你知道原始数组的值以及 d1,d2,…,dm 的值。结果发现数值 c1,c2,…,cm

丢失了。

是否存在一个序列 c1,c2,…,cm

使得对数组 a1,a2,…,an 的修改操作 〈c1,d1,〉,〈c2,d2,〉,…,〈cm,dm〉 的连续应用将其转换为数组 b1,b2,…,bn ?

输入

Input

The first line contains an integer t

(1≤t≤104

) — the number of test cases.

Then follow the descriptions of the test cases.

The first line of each test case contains an integer n

(1≤n≤2⋅105

) — the size of the array.

The second line of each test case contains n

integers a1,a2,…,an (1≤ai≤109

) — the elements of the original array.

The third line of each test case contains n

integers b1,b2,…,bn (1≤bi≤109

) — the elements of the found array.

The fourth line contains an integer m

(1≤m≤2⋅105

) — the number of modification operations.

The fifth line contains m

integers d1,d2,…,dm (1≤dj≤109

) — the preserved value for each modification operation.

It is guaranteed that the sum of the values of n

for all test cases does not exceed 2⋅105, similarly the sum of the values of m for all test cases does not exceed 2⋅105.

输出

Output t lines, each of which is the answer to the corresponding test case. As an answer, output "YES" if there exists a suitable sequence c1,c2,…,cm

, and "NO" otherwise.

You can output the answer in any case (for example, the strings "yEs", "yes", "Yes" and "YES" will be recognized as a positive answer).

Solution

一,当  a[i] == b[i] , 原数组元素和目标数组元素想吻合时,无需对该下标进行操作 d[k],即可达成目标

二,对于一个操作数组 D ,当且仅当最后一个元素 d [i]  是符合要求的 b[k]时,才有可能通过操作 D 来得到数组 B,

若干个 d[i] ,d[i+1] ,d[i+2] 都可以通过对 一个固定的下标 j 进行操作 a[ j ],进行覆盖后,其操作都可以合并为 d[m-1] ,也就是说,无论有多少个多余的,不用的数,只要最后一个数是目标元素B,都可以视为合并后的一部,进而将多余的无用操作进行消耗

代码:

#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_set>
using namespace std;

int t = 0;


bool check(vector<int>& B,vector<int> &D) {

	for (int i : B)
		if (i == D[D.size() - 1])
			return true;
	return false;
}


void solve() {

	int n,m;
	cin >> n;
	vector<int> a(n), b(n);
	unordered_set<int> B(n);

	for (int i = 0; i < n; i++)
		cin >> a[i];


	for (int i = 0; i < n; i++) {
		cin >> b[i];		
	}

	cin >> m;
	vector<int> d(m);
	vector<int> nums;	
	for (int i = 0; i < m; i++) {
		cin >> d[i];
		nums.push_back(d[i]);
		
	}

	//最后一步 后必须是 目标数组中的元素,否则会破坏原有的成果

	vector<int> needs;
	for (int i = 0; i < n; i++)
		if (a[i] != b[i])
			needs.push_back(b[i]);

	
	sort(needs.begin(), needs.end());
	sort(nums.begin(), nums.end());
	int cur = 0;    // 排序 + 双指针 查询存在与否
	for (int i = 0; i < needs.size(); i++) {
		while (cur<m&& nums[cur] < needs[i])
			cur++;
		if (cur<m&& nums[cur] == needs[i])
			cur++;
		else {
			cout << "NO" << endl;
			return;
		}

	}

    if(!check(b,d)){
        cout << "NO" << endl;
        return ;
    }

	cout << "YES" << endl;

	
}


int main() {

	cin >> t;
	while (t--) {
		solve();
	}
}

总结:

1,一开始想到了 d[i]操作会影响已经影响前面已经修改完毕元素,结果没绕过来,一直没想明白为什么只用查询  B.contains( D[m-1]) , 没想到对同一个下标元素多次操作进行覆盖的问题.

2, unordered_set/map 的优化问题,平均情况下,insert() 和 find() 的时间复杂度都是 O (1) 的,但是如果数据出得极端,或者是其它人 hack,是能恶化到 O (N) 的,这里为了避免复杂度退化,使用了 sort() + 双指针, 通过维持一个两数组共同的顺序,做到 nlog( n ) 排序 + n 查询的复杂度,一定程度上能避免被 hack,也正式通过了 hack后加强了的数据集

  • 29
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值