首页 > 其他分享 >SP1557 GSS2 - Can you answer these queries II 题解

SP1557 GSS2 - Can you answer these queries II 题解

时间:2023-11-27 19:44:51浏览次数:37  
标签:tag1 tag2 these 题解 void SP1557 int maxn maxm

SP1557 GSS2 - Can you answer these queries II

更好的阅读体验

扫描线。把询问挂在右端点上,扫描右端点,纵轴仍为序列维。

对于这种出现多次的数只算一次的,记 \(pre_i\) 表示 \(i\) 这个值上一次的出现位置,套路化的可以强制让出现多次的在 \(pre_i<l\wedge i\) 统计,用二维线段树状物维护,但是这道题可以做的更简单。

如果强制让选的右端点就是当前扫描到的右端点的话,设 \(f_i\) 为 \(i\) 到当前的 \(r\) 的出现多次算一次最大子段和,则此时在最右边扩展一位的影响是将 \(pre_{a_i}+1\sim i\) 的 \(f_i\) 全部加 \(a_i\)。这样强制右端点在 \(r\) 的答案即为 \(\max_{i=l}^r f_i\)。可以线段树维护。

但是我们需要求的是右端点 \(l\leq i\leq r\) 的答案。这里的 \(\geq l\),但是去掉这个限制也是无所谓的,因为我们已经限制了左端点的取值,只要把线段树上初值全部设成 \(0\),不合法的区间答案正好是 \(0\),也正好处理了题目中可以一个都不选的限制。这样线段树历史最值维护一下即可,复杂度 \(\mathcal O(m\log n)\)。

	int n,m,ans[100010],a[100010],c[200010];
	vector<pii> ve[100010];
	namespace Segment
	{
		struct{int l,r,maxm,maxn,tag1,tag2;}t[400010];
		inline void update(int p){t[p].maxn=max(t[p*2].maxn,t[p*2+1].maxn),t[p].maxm=max(t[p*2].maxm,t[p*2+1].maxm);}
		inline void down(int p,int tag1,int tag2){t[p].maxm=max(t[p].maxm,t[p].maxn+tag2),t[p].maxn+=tag1,t[p].tag2=max(t[p].tag2,t[p].tag1+tag2),t[p].tag1+=tag1;}
		inline void spread(int p){down(p*2,t[p].tag1,t[p].tag2),down(p*2+1,t[p].tag1,t[p].tag2),t[p].tag1=t[p].tag2=0;}
		void build(int p,int l,int r)
		{
			t[p].l=l,t[p].r=r;
			if(l==r)return;
			int mid=l+((r-l)>>1);
			build(p*2,l,mid),build(p*2+1,mid+1,r);
		}
		void modify(int p,int l,int r,int k)
		{
			if(l<=t[p].l&&r>=t[p].r)return down(p,k,k);
			spread(p);
			if(l<=t[p*2].r)modify(p*2,l,r,k);
			if(r>t[p*2].r)modify(p*2+1,l,r,k);
			update(p);
		}
		int ask(int p,int l,int r)
		{
			if(l<=t[p].l&&r>=t[p].r)return t[p].maxm;
			spread(p);int s=-INF;
			if(l<=t[p*2].r)s=max(s,ask(p*2,l,r));
			if(r>t[p*2].r)s=max(s,ask(p*2+1,l,r));
			return s;
		}
		void print(int p)
		{
			write(t[p].l),write(t[p].r),write(t[p].maxn),write(t[p].maxm,'\n');
			if(t[p].l==t[p].r)return;
			spread(p);
			print(p*2),print(p*2+1);
		}
	}
	using namespace Segment;
	inline void mian()
	{
		read(n),build(1,1,n);int x,y;
		for(int i=1;i<=n;++i)read(a[i]);
		read(m);
		for(int i=1;i<=m;++i)read(x,y),ve[y].eb(mp(x,i));
		for(int i=1;i<=n;++i)
		{
			modify(1,c[a[i]+100000]+1,i,a[i]),c[a[i]+100000]=i;
			for(auto p:ve[i])ans[p.se]=ask(1,p.fi,i);
		}
		for(int i=1;i<=m;++i)write(ans[i],'\n');
	}

标签:tag1,tag2,these,题解,void,SP1557,int,maxn,maxm
From: https://www.cnblogs.com/WrongAnswer90-home/p/17860263.html

相关文章

  • CF1900 D Small GCD 题解
    LinkCF1900DSmallGCDQuestion定义\(f(x,y,z)=\gcd(a,b)\),其中\(a,b\)为\(x,y,z\)中较小的那两个数给出数组\(a\),求\[\sum\limits_{i=1}^n\sum\limits_{j=i+1}^n\sum\limits_{k=j+1}^nf(a_i,a_j,a_k)\]三个求和符号本质上就是选数组\(a\)中的三个数,也就是说,数......
  • P3375 【模板】KMP( 普及/提高− ) 题解
    题目传送门思路:首先我们要学习一下\(KMP\)算法,不会的可以看这个大佬的文章那么我们就直接开始讲思路了。针对于每一位,\(kmp\)算法已经预处理出了一个对应\(kmp\)数组的单元,映射着如果此位失配,它可能的最靠后的一个重新开头是哪一个。让我们举一个例子:假如让\(aaab\)与......
  • P9447 [ICPC2021 WF] Spider Walk 题解
    更好的阅读体验很有意思的一道题。设\(f_i\)表示第\(i\)根线的答案,首先有一个关键结论:任意两根相邻的线答案只差一定小于\(1\)。原因显然,可以在无限远的地方加一根线来构造。该结论可以扩展一下,对于距离为\(d\)的两根线,答案之差不会超过\(d\)。考虑进行倒着加线,考虑加......
  • CF1900 C Anji's Binary Tree 题解
    LinkCF1900CAnji'sBinaryTreeQuestion给出一个树,每个节点上有一个字母L/R/U,从\(1\)号根节点开始,L表示接下来走到左节点,R表示接下来走到右节点,U表示接下载走到父节点问,最少修改几个节点上的字母使得从根节点走到叶子节点Solution定义\(F_x\)表示从\(x\)走到叶......
  • P7626 [COCI2011-2012#1] MATRIX( 普及/提高− ) 题解
    题目传送门思路:首先思考暴力,\(O(n^4)\)的时间复杂度,不行。那么我们这里就要运用到一点前缀和的知识了。我们可以用前缀和对两条对角线进行计数。每个点有两个对角线运算。差不多是\(O(n^2)\)到\(O(n^3)\)的时间复杂度。而\(n\leq400\)稳过。Code:#include<bits/stdc......
  • 复旦大学数学学院23级高等代数I期中考试精选大题解答
    四、求解下列线性方程组,其中$a_1,\cdots,a_n,b$为参数且$\sum\limits_{i=1}^na_i\neq0$:$$\begin{cases} (a_1+b)x_1+a_2x_2+a_3x_3+\cdots+a_nx_n=0,\\ a_1x_1+(a_2+b)x_2+a_3x_3+\cdots+a_nx_n=0,\\ a_1x_1+a_2x_2+(a_3+b)x_3+\cdots+a_nx_n=0,\\ \hfill\cdots\cdots......
  • CF1900 B Laura and Operations 题解
    LinkCF1900BLauraandOperationsQuestion给出\(1,2,3\)的个数\(a,b,c\)可以分别减少两个不同的数,增加一个与两个数都不同的数问,是否能经过一些操作使得就剩下\(1\)或\(2\)或\(3\)Solution先考虑\(1,2,3\)其实是等价的,所以我们只需要考虑把\(2,3\)全都变成......
  • CF1900 A Cover in Water 题解
    LinkCF1900ACoverinWaterQuestion给出一个\(n\)个格子,有些格子被堵塞了,有些格子是空的,我需要在进行一些操作,使得所有空的格子里面都有水操作1:给任意一个格子装上水操作2:把一格水从一个地方搬运到另外一个空的格子里如果一个空的格子的相邻的两个格子都有水,那么这......
  • Live Server插件打开浏览器时:该网页无法正常运作,127.0.0.1未发送任何数据的问题解决
    一、问题复现今天使用VsCode写HTML代码时,使用LiveServer打开预览时,发现浏览器显示“该网页无法正常运作,127.0.0.1未发送任何数据”的问题。二、解决办法1.在左侧工具栏找到扩展商店,找到LiveServer,然后点击对应的小齿轮,进入插件设置。2.选择ExtensionSettings3.进入......
  • ABC330 A-E 题解
    ABC330题解AtCoderBeginnerContest330A-CountingPasses思路:枚举一遍,当前数大于\(L\)使\(ans+1\)即可.代码:#include<iostream>#defineintlonglongusingnamespacestd; intn,l,ans;intx; signedmain(){ cin>>n>>l; for(inti=1;i&......