首页 > 其他分享 >NOI2024 集合 题解

NOI2024 集合 题解

时间:2024-07-21 12:42:58浏览次数:14  
标签:哈希 int 题解 long 合法 NOI2024 ull 集合 ri

给个链接:集合

很神秘的题目。基本上看到之后就可以想到哈希。

首先想到一个比较神秘的暴力。就是对于每个询问,扫一遍所有\(a\) 中的数出现的位置,把它弄成一个哈希值(具体怎么弄随意)存到 set 里,然后看看是不是和 \(b\) 中的数出现的位置这样操作后的集合完全相等。事实上就是判断是否对于所有在 \(a\) 中这个区间内出现的数 \(x\),都存在一个在 \(b\) 中出现的不同的数 \(y\),使得 \(x,y\) 出现的位置完全相同。这样做应该是有 \(70\) 分的,但是显然不够。

然后我们考虑一个事情,对于每一个 \(i\),\([i,j]\) 这个区间合法在 \(j\) 尽可能小的时候最有可能成立。换句话说有单调性,可以二分。

但是,二分是没有必要的,我们可以用双指针做的更好。因为,如果 \([i,j]\) 合法,\([i+1,j]\) 存在,那么 \([i+1,j]\) 合法。

所以我们对每个 \(i\) 找出最靠右的 \(j\) 且满足 \([i,j]\) 合法,然后就可以 \(O(1)\) 回答询问。时间复杂度 \(O(n+q)\)。

这里为了保险,把每个位置的值也做了哈希,用 \(p_i\) 存储。

给个代码:

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define N 200005
using namespace std;
int n,m,q,a[N][3],b[N][3];
ull nowa[N],nowb[N],suma,sumb,p[N];
int ri[N];//使[i,j]合法的最靠右的j
ull get_rnd(ull x){
	return x*x*x;//随便变换一下
}
void work(int id,int type){
	for(int j=0;j<3;j++){
		ull i=a[id][j];
		suma-=get_rnd(nowa[i]);//把原来的值减掉
		nowa[i]+=type*p[id];//看情况加上或减去这个位置的哈希值
		suma+=get_rnd(nowa[i]);//加上现在的值
	}
	for(int j=0;j<3;j++){//这里同理
		ull i=b[id][j];
		sumb-=get_rnd(nowb[i]);
		nowb[i]+=type*p[id];
		sumb+=get_rnd(nowb[i]);
	}
}
signed main(){
	srand(time(0));
	cin>>n>>m>>q;
	for(int i=1;i<=n;i++){
		for(int j=0;j<3;j++){
			cin>>a[i][j];
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=0;j<3;j++){
			cin>>b[i][j];
		}
	}
	for(int i=1;i<=n;i++){
		ri[i]=n;
	}
	for(int i=1;i<=n;i++){
		p[i]=rand()*rand()+923;
	}
	work(1,1);
	for(int i=1,j=1;i<=n;i++){
		while(j<=n&&suma==sumb){//如果当前仍然合法
			j++;
			if(j>n)break;
			work(j,1);
		}
		ri[i]=min(ri[i],j-1);
		work(i,-1);//i要右移,所以撤掉这一位的贡献
	}
	while(q--){
		int l,r;
		cin>>l>>r;
		cout<<(ri[l]>=r?"Yes\n":"No\n");
	}
	return 0;
}

标签:哈希,int,题解,long,合法,NOI2024,ull,集合,ri
From: https://www.cnblogs.com/zxh923aoao/p/18314343

相关文章

  • B3956 [GESP202403 三级] 字母求和 题解
    B3956[GESP202403三级]字母求和题解当时在考试,3分钟A了,结果第二题T了。#include<bits/stdc++.h>usingnamespacestd;constintN=1e5+2;constintN1=1e3+2;typedeflonglongll;typedefunsignedlonglongull;#definefo(i,n,m)for(inti=n;i<=m;i++)......
  • 【科大讯飞笔试题汇总】2024-07-20-科大讯飞秋招提前批(研发岗)-三语言题解(Cpp/Java/
    ......
  • 题解:Codeforces Round 960 (Div. 2) B
    B.ArrayCrafttimelimitpertest:1secondmemorylimitpertest:256megabytesinput:standardinputoutput:standardoutputForanarray\(b\)ofsize\(m\),wedefine:themaximumprefixpositionof\(b\)isthesmallestindex\(i\)thatsat......
  • 洛谷 P1162 填涂颜色题解
    题目链接填涂颜色题目描述由数字\(0\)组成的方阵中,有一任意形状的由数字\(1\)构成的闭合圈。现要求把闭合圈内的所有空间都填写成\(2\)。例如:\(6\times6\)的方阵(\(n=6\)),涂色前和涂色后的方阵如下:如果从某个\(0\)出发,只向上下左右\(4\)个方向移动且仅经过其他\(0\)......
  • 题解:Codeforces Round 960 (Div. 2) A
    A.SubmissionBaittimelimitpertest:1secondmemorylimitpertest:256megabytesinput:standardinputoutput:standardoutputAliceandBobareplayingagameinanarray\(a\)ofsize\(n\).Theytaketurnstodooperations,withAlicestarting......
  • InvalidDimensionException:嵌入维度 384 与集合维度 1536 不匹配
    我正在Chromadb上编写python代码来创建矢量数据库我尝试在chromadb中创建包含嵌入的集合。在使用包括嵌入的矢量数据库创建索引期间,我面临这个问题出现错误信息“InvalidDimensionException:嵌入维度384与集合维度1536不匹配”的原因是,你正尝试将维度为384的......
  • Java之集合底层-数据结构
    Java集合之数据结构1概述数据结构是计算机科学中研究数据组织、存储和操作的一门学科。它涉及了如何组织和存储数据以及如何设计和实现不同的数据操作算法和技术。常见的据结构有线性数据结构(含数组、链表、栈和队列等),非线性数据结构(树、图等)。注意:不同的数据结构适用于......
  • Java 语言及其常用集合类的操作,以及反射机制与注解
    目录一、Java语言概述二、Java集合框架ArrayList操作示例:HashMap操作示例:三、反射机制1.反射的示例五、总结Java是一种广泛使用的高级编程语言,因其平台独立性、简洁性及丰富的API而备受开发者青睐。一、Java语言概述 Java语言由JamesGosling等人......
  • NOI2024 总结
    赛时经历Day1想了1h的t1,然后思路不是很清晰,写了1h。想t2,顺着擂台赛想下去,可以分成\(k\)个一组,每组\(\dfrac{k(k-1)}2\)次查询,然后选出一个最大的组成一个新的序列。过了一会儿,想到dp这个过程,得到82pts。剩下大约1h30min,想t3,一直在往计数+容斥的方向......
  • [题解]P4166 [SCOI2007] 最大土地面积
    P4166[SCOI2007]最大土地面积解法\(1\)-\(O(n^2)\)我们运用调整法,可以证明这个四边形的\(4\)个顶点一定都在凸包的顶点上,具体来说:\(\textbf{Proof:}\)首先我们知道,凸包内,到某条直线距离最大的点一定包括\(1\)个顶点。接下来我们考虑一个凸包内的四边形:我们过它的对角......