首页 > 其他分享 >[CEOI2018] Lottery 题解

[CEOI2018] Lottery 题解

时间:2024-07-22 17:07:21浏览次数:15  
标签:CEOI2018 Lottery int 题解 who Theta neq sim dis

前言

题目链接:洛谷

题意简述

给出序列 \(a_1 \ldots a_n\) 和常数 \(l \leq n\),定义:

\[\operatorname{dis}(i, j) = \sum _ {k = 0} ^ {l - 1} [a_{i + k} \neq a_{j + k}] \qquad (i, j \in [1, n - l + 1]) \]

每次询问一个 \(k\),求对于所有 \(i \in [1, n - l + 1]\),求 \(\sum \limits _ {j \neq i} [\operatorname{dis}(i, j) = k]\)。

题目分析

暴力不用说,考虑如何优化。这类问题我们思考能不能省略重复的计算。例如,对于 \(l_1 \sim r_1\) 和 \(l_2 \sim r_2\) 的 \(\operatorname{dis}\) 已经求出,那么对于 \(l_1 + 1 \sim r_1 + 1\) 和 \(l_2 + 1 \sim r_2 + 1\) 的 \(\operatorname{dis}\) 只需要在原来基础上减去 \([l_1 \neq l_2]\),再加上 \([r_1 + 1 \neq r_2 + 1]\)。是 \(\Theta(1)\) 的。

具体地讲,对于这两个区间,它们的差值的可能性是 \(\Theta(n)\) 的,我们枚举这个差值,然后将这两个区间向右平移,用上述算法计算,并累加。注意到这样会不重不漏地统计到每一个区间的答案。时间复杂度 \(\Theta(n ^ 2)\)。

另外,由于特殊的空间限制,不妨将询问离线并离散化,空间复杂度就降到了 \(\Theta(nq)\)。

代码

略去了快读快写。

#include <cstdio>
#include <algorithm>
using namespace std;

int n, m, q, val[10010];
int cnt[110][10010];
int qry[110], rq[110], who[10010];

signed main() {
	fread(buf, 1, MAX, stdin);
	read(n), read(m);
	for (int i = 1; i <= n; ++i) read(val[i]);
	read(q);
	for (int i = 1; i <= q; ++i) read(qry[i]), rq[i] = qry[i];
	sort(rq + 1, rq + q + 1);
	for (int i = 1; i <= q; ++i) who[rq[i]] = i;
	who[m + 1] = q + 1;
	for (int i = m; i >= 0; --i) !who[i] && (who[i] = who[i + 1]);
	for (int i = 1; i + m <= n; ++i) {  // 两个区间的差
		int tot = 0;
		for (int j = 1; j <= m; ++j) tot += val[j] != val[j + i];
		for (int l1 = 1, r1 = m, l2 = 1 + i, r2 = m + i; r2 <= n; ++l1, ++l2, ++r1, ++r2) {
			++cnt[who[tot]][l1], ++cnt[who[tot]][l2];
			tot -= val[l1] != val[l2];
			tot += val[r1 + 1] != val[r2 + 1];
		}
	}
	for (int i = 1; i <= q; ++i)
		for (int j = 1; j + m - 1 <= n; ++j)
			cnt[i][j] += cnt[i - 1][j];
	for (int i = 1; i <= q; ++i) {
		for (int j = 1; j + m - 1 <= n; ++j)
			write(cnt[who[qry[i]]][j]), putchar(' ');
		putchar('\n');
	}
	fwrite(obuf, 1, o - obuf, stdout);
	return 0;
}

后记 & 反思

考虑重复计算并优化是关键。另外,枚举两个区间的位置关系,并做到不重不漏的统计也是值得注意的。

标签:CEOI2018,Lottery,int,题解,who,Theta,neq,sim,dis
From: https://www.cnblogs.com/XuYueming/p/18316425

相关文章

  • [COCI2015-2016#1] RELATIVNOST 题解
    前言题目链接:洛谷。这道题有很多做法,但是模拟赛寄了,故记之。题意简述给你两个长为\(n\)的序列\(A\)和\(B\),和一个常数\(c\leq20\),有\(q\)次修改。每次修改后求:\[\large\sum_{S\subseteq\lbracei\rbrace_{i=1}^{n}\land|S|\geqc}\prod_{x\inS......
  • [ARC176E] Max Vector 题解
    题目链接点击打开链接题目解法这个题的一个转化很关键:把一次操作\(j\)等价看作必须满足\((\forall_{1\lei\len}X_i\gea_{j,i})|(\forall_{1\lei\len}Y_i\gea_{j,i})=1\)正确性是显然的另外的一个关键思路是网络流有了上面的转化,我们考虑切糕模型(其实接下来都好想......
  • 题解 B3694 数列离散化
    link简而言之,离散化就是把一个数列转化为由小到大的排名来缩小范围。离散化需要这个题不用数字本身。举个例子:-200244879914993235793离散化后就是:15243\(-2002\)最小,所以它对应\(1\)\(448799\)最大,所以它对应\(5\)实现考虑如何实现。首先由于离散化前后......
  • 【Web】ImaginaryCTF 2024 部分题解
    目录journalcrystalsP2CreadmeTheAmazingRacejournal简单的assert命令拼接payload:?file=test','..')===true||system("echo`tac/flag-cARdaInFg6dD10uWQQgm.txt`")||strpos('testcrystalsdocker-compose.yml里让服务报错读到泄露的hos......
  • 题解:牛客周赛 Round 52 A
    A两数之和时间限制:C/C++1秒,其他语言2秒空间限制:C/C++262144K,其他语言524288KSpecialJudge,64bitIOFormat:%lld题目描述对于给定的正整数\(z\),你需要寻找两个不同的正整数\(x\)和\(y\),使得\(x+y=z\)成立。如果不存在这样的\(x\)和\(y\),你只需要输出NO。......
  • ABC363 DEF 题解
    ABC363DEF题解前情提要:赛时过了ABCE。D-PalindromicNumber题目链接其实赛时已经看出了一些性质,但没想完做法,赛后看题解才发现这么简单/fn首先,为了方便,我们不把\(0\)视作回文数(因此需要特判一下\(n=1\)的情况)。下面要证明:\(d\)位回文数有\(10^{\left\lfloor\f......
  • 题解 P1115 最大子段和
    link容易想到朴素做法:for(intl=1;i<=n;++i){for(intr=1;j<=n;++j){intv=s[r]-s[l-1];ans=max(ans,v);}}但是显然\(\mathrm{\color{#052242}TLE}\)再回头看代码:想要v最大,只需要\(\large{S_{l-1}}\)最小即可......
  • 题解:P7482 不条理狂诗曲
    题解:P7482不条理狂诗曲本题解借鉴blossom_j大佬思路,但这位大佬的题解似乎没放正确代码。题意对于每一个\(a\)的子区间\(a_{l\dotsr}\),求选择若干个不连续的数的和的最大值,对答案取模\(10^{9}+7\)。思路主要算法:分治。计算跨过中点\(mid\)的区间的\(f\)之和。首......
  • P3041 [USACO12JAN] Video Game G 题解 AC自动机
    本题是一道AC自动机上的dp。首先不难想到状态定义f(i,j)表示仅考虑前i 个位置,第i 个字符是j 的分数,但无法转移,所以考虑将j这一维转化为表示AC自动机上的点。再定义val(i)表示以i 结尾的所有技能种数,则转移方程为f(i,j)=max(f(i,j),f(i-1,father(j)+val(j......
  • Loj P10064 黑暗城堡 题解 最短路径树记数
    这道题是一道最短路径树问题。首先,什么是最短路径树呢?定义一个图的最短路径树表示一个图上的生成树,且根节点到图上任一点的距离等于原图上两者之间的距离。而不难发现,题目其实是在求图上最短路径树记数。首先,建出最短路径树。枚举每条边,判断边两个端点到根的距离之差是否为......