CCF-CSP 202112-2 序列查询新解子区间

Posted nefu-ljw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CCF-CSP 202112-2 序列查询新解子区间相关的知识,希望对你有一定的参考价值。

题目链接

http://118.190.20.162/view.page?gpid=T137

思路

有点类似尺取法枚举区间。这题是先固定一个区间,再在这个区间内遍历子区间。

遍历 f ( i ) f(i) f(i)值相同的区间,假设每个区间范围[L, R],再在[L, R]内遍历 g ( i ) g(i) g(i)值相同的子区间,这样在计算时就能保证子区间的 f ( i ) f(i) f(i)值全部相同、 g ( i ) g(i) g(i)值全部相同。比较关键的地方是要找到 g ( i ) g(i) g(i)及其区间右端点的两个对应关系:
g ( i ) = i / r g(i)=i/r g(i)=i/r

g ( i ) _ e n d p o s = [ g ( i ) + 1 ] ∗ r − 1 g(i)\\_endpos=[g(i)+1]*r-1 g(i)_endpos=[g(i)+1]r1
g ( i ) _ e n d p o s g(i)\\_endpos g(i)_endpos表示取值为 g ( i ) g(i) g(i)的区间的右端点位置。

AC代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int n,N,a[maxn];
int main()

	ios::sync_with_stdio(false);
	cin>>n>>N;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	a[0]=0; a[n+1]=N;
	int r=N/(n+1);
	ll ans=0;
	for(int i=0;i<=n;i++)
		int L=a[i];
		int R=a[i+1]-1;
		// 当前区间[L,R]
		int fi=i; // [L,R]区间内f(i)值相同,均为fi
		// 接下来在[L,R]区间内遍历g(i)的各个区间
		// 每次保证遍历的子区间内的g(i)值相同
		int startpos=L;
		while(startpos<=R)
			int gi=startpos/r; // g(i)值
			int endpos=min((gi+1)*r-1,R); // g(i)值相同的最后一个位置,注意不要超过R
			// [startpos,endpos]区间内的g(i)值相同,均为gi
			// [startpos,endpos]是[L,R]的子区间,保证fi相同,gi相同,直接计算即可
			ans+=abs(fi-gi)*(endpos-startpos+1);
			startpos=endpos+1;
		
	
	printf("%lld\\n",ans);
	return 0;

以上是关于CCF-CSP 202112-2 序列查询新解子区间的主要内容,如果未能解决你的问题,请参考以下文章

CSP 202112-2 序列查询新解 python 离散+二分法

CCF-CSP题解 201709-3 JSON查询

CCF-CSP 201612 赛题训练

CCF-CSP C/C++ 202009-1 称检测点查询 题解

CCF-CSP刷题库11-18

动态规划_基础_任意子区间序列求和问题_滑动窗口解法_多种思路_分治思想演变