首页 > 其他分享 >[题解]UVA11235 Frequent values

[题解]UVA11235 Frequent values

时间:2024-06-02 14:21:23浏览次数:25  
标签:lg int 题解 UVA11235 num values sim 100010 Frequent

https://www.luogu.com.cn/problem/UVA11235

没看到多测调了半天

每组数据给定\(n,q\)。接下来给出一个长度为\(n\)的不降序列\(A\)。接下来\(q\)次询问,每次询问给定\(l,r\),求\(A_{l\sim r}\)中出现最多的那个数出现了多少次。

\(1\le n,q \le 10^5\)。


序列不降,意味着一个数在序列中一定是连续存在的。

那么我们可以把连续相同的元素分成一段(游程编码)。

设一共分了\(len\)段,第\(i\)段的左边界是\(l\),右边界是\(r\)。\(A_i\)在第\(num[i]\)段。

查询时,对于输入的\(x,y\)。我们的答案就是下面三种情况的最大值:

  • \(x\sim x\)所在组的右边界,即\(r[num[x]]-x+1\)。
  • \(y\)所在组的左边界\(\sim y\),即\(y-l[num[y]]+1\)。
  • \(x\)所在组的下一组\(\sim y\)所在组的上一组中,最大组的大小,即\(\max\limits_{num[x]<i<num[y]}(r[i]-l[i]+1)\)。这一操作可以用ST表来维护。

实现细节:

  • 如果\(num[x]=num[y]\)(\(x,y\)在同一组),则直接输出\(y-x+1\)。
  • 否则,答案就是上面\(3\)种情况的最大值,但需要注意调用query(num[x]+1,num[y]-1),可能会出现\(num[x]+1>num[y]-1\)的情况,此时\(query\)需要返回\(0\)。

每个测试点时间复杂度\(O(n\log n+q)\)。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n,q,a[100010];
int siz,cur=INT_MIN;
int l[100010],r[100010],lg[100010];
int len,num[100010];
int maxx[100010][30];
void init(){
	lg[0]=-1;
	for(int i=1;i<=len;i++)
		lg[i]=lg[i/2]+1,maxx[i][0]=r[i]-l[i]+1;
	for(int i=1;i<=lg[len];i++){
		for(int j=1;j+(1<<i)-1<=len;j++){
			maxx[j][i]=max(maxx[j][i-1],maxx[j+(1<<(i-1))][i-1]);
		}
	}
}
int query(int l,int r){
	if(l>r) return 0;
	int t=lg[r-l+1];
	return max(maxx[l][t],maxx[r-(1<<t)+1][t]);
}
int main(){
	while(cin>>n>>q){
		len=0;
		for(int i=1;i<=n;i++) cin>>a[i];
		for(int i=1;i<=n;i++){
			if(a[i]!=cur){
				r[len]=i-1;
				l[++len]=i;
				cur=a[i];
			}
			num[i]=len;
		}
		r[len]=n;
		init();
		while(q--){
			int x,y;
			cin>>x>>y;
			if(num[x]==num[y]) cout<<y-x+1<<endl;
			else cout<<max(max(r[num[x]]-x+1,y-l[num[y]]+1),
				query(num[x]+1,num[y]-1))<<endl;
		}
	}
	return 0;
}

标签:lg,int,题解,UVA11235,num,values,sim,100010,Frequent
From: https://www.cnblogs.com/Sinktank/p/18227037

相关文章

  • CF1228E Another Filling the Grid 题解
    tag:容斥原题+组合数设F[i]F[i]F[i]表示至少......
  • [leetcode 第 400 场周赛]题解
    第一题:classSolution{publicintminimumChairs(Strings){intx=0;intans=0;for(inti=0;i<s.length();i++){if(s.charAt(i)=='E'){x--;if(x<0){ans++;x=0;......
  • [题解]P4381 [IOI2008] Island
    P4381[IOI2008]Island题意:给定一个基环树森林,求每个基环树的直径之和。我们发现,一棵基环树的直径只有下面两种情况:环上的某一点作为根的子树的直径。环上有两点,每个点引出一条链,然后再将这两点相连。对于第一种情况,我们仅需用树形dp的方法求出每个子树的直径(见OIWiki-......
  • 《扶苏的问题》题解
    《扶苏的问题》题解原题传送门:P1253扶苏的问题PS:请先阅读完题面,在继续观看题意概述:​ 对于给定的数列\({a_1,a_2,a_3……a_n}\),进行以下三个操作:​ 1.change 将区间\([L,R]\)的值修改为\(X\);​ 2.add 将区间\([L,R]\)的值加上为\(D\);​ 3.query 查询区间\([......
  • WSL2--DNS解析问题解决
    1.问题xurong@DESKTOP-SOE9MG1:~/.ssh$sudoaptupdateIgn:1http://security.ubuntu.com/ubuntunoble-securityInReleaseIgn:2http://archive.ubuntu.com/ubuntunobleInReleaseIgn:3http://archive.ubuntu.com/ubuntunoble-updatesInReleaseIgn:4http://archive......
  • CF1961E Turtle and Intersected Segments 题解
    题目链接点击打开链接题目解法不是,我这咋不会做/fn边数很多的最小生成树有一个方法是\(boruvka\),但这个处理完全图的比较方便另一个方法是用到一个\(trick\):连出的图中的环,可以删去最长边扫描线是容易想到的,主要是如何把连的边数缩减到合理的范围内考虑扫描线到当前时刻......
  • 第二十一届宁波大学程序设计竞赛(同步赛) A,B,D,F,H题解
    链接:第二十一届宁波大学程序设计竞赛(同步赛)_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ(nowcoder.com)A:直接输出不多解释B:B-LoveYouGuys_第二十一届宁波大学程序设计竞赛(同步赛)(nowcoder.com)#include<bits/stdc++.h>usingnamespacestd;intx,y......
  • atcoder350,351,352,353,354,355期部分题解
    声明:有些题感觉已经说到很明白了,就先不写代码了,有空会补上目录350D: newfriend350E:toward0351D:GridandMagnet352D:permutation subsequence353C:sigmaproblem353D:anothersigmaproblem354C:atcodermagics355C:bingo2355D:intersectingintervals......
  • 【问题解决】MySQL恢复数据库报错Unknown command '\''.
    问题使用以下命令备份恢复数据库,恢复失败提示ERRORatline39595:Unknowncommand'\''.#备份数据库mysqldump-uusername-p--no-create-db-Rdatabasename>dump.sql#恢复数据库mysql-uusername-pdatabasename2<dump.sql问题原因及解法原因:中文字符的问题......
  • P6156 简单题 题解
    P6156简单题题解题目大意题目传送门给定\(n,k\),求\(\sum_{i=1}^n\sum_{j=1}^n(i+j)^k\gcd(i,j)\mu^2(\gcd(i,j))\)。\(1\leqn\leq5\times10^6\)题目分析先推导一波式子:\[\begin{aligned}ans&=\sum_{i=1}^n\sum_{j=1}^n(i+j)^k\gcd(i,j)\mu^2(\gcd(i,j))\\&=......