首页 > 其他分享 >codeforces round 977 (div.2) C2(访问set的第一个元素,观察数据规律-出现次序,用set记录数字第一次出现的位置)

codeforces round 977 (div.2) C2(访问set的第一个元素,观察数据规律-出现次序,用set记录数字第一次出现的位置)

时间:2024-10-13 23:25:36浏览次数:1  
标签:977 fis set int 位置 codeforces flag 出现

解题历程:

我首先想到的是等效法,每一次操作可以等效为每次将第一个人抽出放入一组,后面的人往前移,而该组的人就是可以任意放置的人,当b中后面再出现与前一个相同的人时,就不进行操作,当b中出现不同的人时,就看看这组中有没有这个人,有的话就下一个循环,没有的话就看看这个新的人是否按a中的顺序出现,若是没有就是NO,否则将这个人放入那个组中,一直到最后都没问题,那结果就是YES,而这个组可以用长度为n的数组存储,1表示出现过,0表示没出现过。

正确思路:

若是C1的情况,则只需要将b中数第一次出现的位置记录下来即可,再看看他们是不是按照a的顺序出现,若是是的话就是YES,否则就是NO,如果是C2的情况,需要更改数组b的值,那么就需要将b中的所有数出现的位置记录下来,因为改变一个数后,原本第二次出现的数可能变成第一次出现,所以可以用set容器记录数出现的所有位置,set还会自动排序,set中的第一个数就是该数第一次出现的位置,那么每次更改的时候就只需要删除原数的set中的位置,再在新数的set中加入该位置即可,然后根据a的顺序查找他们第一次出现的位置是否是单调递增的,在这个过程中有一个技巧,就是用一个变量flag来记录状态,若是出现一次递减的话就让其加1,若是去掉一个数,则可以减去该数对flag的影响,若是加上一个数,则可以加上该数对flag的影响,这是一个微观的处理思想,因为改变一个数只会对两边的增减会有影响

代码:

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

void solve() {
	int n,m,q;
	cin>>n>>m>>q;
	vector<int>a(n+1);
	vector<int>pos(n+1);//为了确定a的前后是谁 
	vector<int>b(m+1);
	vector<set<int>>s(n+1);
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		pos[a[i]]=i;
		s[a[i]].insert(m+1);
	}
	for(int i=1;i<=m;i++){
		cin>>b[i];
		s[b[i]].insert(i);
	}
	vector<int>fis(n+1);
	for(int i=1;i<=n;i++){
		fis[i]=*s[i].begin();
	}
	int flag=0;
	for(int i=2;i<=n;i++){
		if(fis[a[i-1]]>fis[a[i]])flag++;
	}
	if(!flag)cout<<"YA"<<endl;
	else cout<<"TIDAK"<<endl;
	auto update=[&](int i){
		if(i>1)
		flag-=fis[a[i-1]]>fis[a[i]];
		if(i<n)
		flag-=fis[a[i]]>fis[a[i+1]];
		fis[a[i]]=*s[a[i]].begin();
		if(i>1)
		flag+=fis[a[i-1]]>fis[a[i]];
		if(i<n)
		flag+=fis[a[i]]>fis[a[i+1]];
	};
	while(q--){
		int v,d,old;
		cin>>v>>d;
		old=b[v];
		b[v]=d;
		s[old].erase(v);
		s[d].insert(v);
		update(pos[old]);
		update(pos[d]);
		if(!flag)cout<<"YA"<<endl;
		else cout<<"TIDAK"<<endl;
	}
}

int main(void )
{   
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
    int test=1;
    cin>>test;
	
    while(test--)
    {
    	solve();
	}
        
    return 0;
}


反思:

  1. 可以用*set.begin()的方式访问set的第一个元素

  2. 若是涉及到状态,比如有几个递增和递减则可以用变量来记录

  3. 可以用pos[a[i]]=i,记录a[i]的位置,可以反向用来查找a中元素

  4. 以后解题时可以列出合法的数据,然后仔细观察数据

  5. 观察数据时除了可以用等效的方法,还可以观察数据出现的次序

  6. 以后可以用set记录所有数的出现次序

标签:977,fis,set,int,位置,codeforces,flag,出现
From: https://www.cnblogs.com/cavendishboys/p/18463201

相关文章

  • Codeforces Round 899 (Div. 2)题解记录
    题目链接:https://codeforces.com/contest/1882A.IncreasingSequence从1开始慢慢和\(a[i]\)的所有值比较,注意最后一个位置特判下#include<iostream>#include<string.h>#include<map>#include<vector>#include<set>#include<unordered_set>#include<......
  • Java中的Iterator接口,以及HashSet和TreeSet
    在Java编程中,`Iterator`接口是一个非常重要的概念,它为我们提供了一种统一且方便的方式来遍历集合(如`List`、`Set`、`Map`等数据结构中的元素,不过遍历`Map`时稍显特殊,通常是遍历其键值对的集合视图)。##一、Iterator接口的定义与方法`Iterator`接口位于`java.util`包中,它定义......
  • day07=集合进阶(Set、Map集合)
    day07——集合进阶(Set、Map集合)一、Set系列集合1.1认识Set集合的特点Set集合是属于Collection体系下的另一个分支,它的特点如下图所示下面我们用代码简单演示一下,每一种Set集合的特点。//Set<Integer>set=newHashSet<>(); //无序、无索引、不重复//Set<Integer>set=......
  • ab压测的选项、示例和主要关注的指标意义以及ab压测问题Connection reset by peer (10
    一、ab压测的选项、示例和主要关注的指标意义1.ab压测的一些选项-nrequests    全部请求数-cconcurrency 并发数-ttimelimit   最传等待回应时间-ppostfile    POST数据文件-Tcontent-typePOSTContent-type-vverbosity   Howmuchtroubl......
  • 【代码】集合set
    哈喽大家好,我是@学霸小羊,今天来讲一讲集合(set)。在数学上,集合长这样:那今天就来讲一讲编程上的集合。集合的定义:把一些元素按照某些规律放在一起,就形成了一个集合。比如说每个班级就是一个集合,竞赛班也是一个集合,每间学校也是一个集合,等等。集合的特点:确定性、互异性、无序......
  • Codeforces Round 946 (Div. 3)
    E.MoneyBuysHappiness题意:给你\(m\)个月,每个月可以赚\(x\)元,每个月你都有一次机会花费\(c_i\)元,获得\(h_i\)的幸福。(当然你目前得有足够的钱)。求出能够获得的最大幸福值。思路:我们可以求出获得\(i\)幸福值所需的最小花费,然后判断能否有足够的钱即可。考虑如何求解,把......
  • Windows平台软件打包工具(inno setup)的使用
    目录Windows平台软件打包工具(innosetup)的使用innosetup中文版下载地址innosetup介绍软件特色Innosetup打包教程Windows平台软件打包工具(innosetup)的使用innosetup中文版下载地址正版下载:https://jrsoftware.org/isdl.php中文版下载:链接:https://pan.baidu.com/s/1Bwg......
  • 利用pytorch的datasets在本地读取MNIST数据集进行分类
    MNIST数据集下载地址:tensorflow-tutorial-samples/mnist/data_setatmaster·geektutu/tensorflow-tutorial-samples·GitHub数据集存放和dataset的参数设置:完整的MNIST分类代码:importtorchimporttorch.nnasnnimporttorch.optimasoptimfromtorchvisionimpor......
  • Solution - Codeforces 622E Ants in Leaves
    首先因为\(1\)点是可以一次性到多个点的,因此不需要考虑\(1\)点的情况,而是转而分析\(1\)的每个子树的情况,最后取\(\max\)。那么对于每个子树,就有每个节点每个时刻至多存在\(1\)个点的性质了。考虑如何去求解。首先一个贪心的想法是肯定是每个蚂蚁越早到一个点越好。于......
  • Vue3,setup()函数与<script setup>到底有什么本质区别?
    文章目录Vue3中`setup()`函数与`<scriptsetup>`的本质区别一、`setup()`函数的基础理解二、`<scriptsetup>`的基础理解三、`setup()`与`<scriptsetup>`的本质区别四、何时使用`setup()`,何时使用`<scriptsetup>`五、`<scriptsetup>`的一些特殊功能六、......