Codeforces Round 920 (Div. 3) F题 根号分治,后缀和,后缀和的后缀和

这篇具有很好参考价值的文章主要介绍了Codeforces Round 920 (Div. 3) F题 根号分治,后缀和,后缀和的后缀和。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Problem - F - Codeforces 

我看的这位UP的视频讲解 :

Codeforces Round 920 (Div. 3) F题 根号分治 详解_哔哩哔哩_bilibili

 

目录

题意:

思路:

后缀和的后缀和:

后缀和的后缀和的中间段如何求:

————

根号分治:

核心代码:


 

题意:

给你个数组,求这个和Codeforces Round 920 (Div. 3) F题 根号分治,后缀和,后缀和的后缀和,CF,算法

s是起始下标,d是间隔gap,k代表第几个数乘以几。

思路:

暴力过不了。需要后缀和预处理。

后缀和的后缀和:

Codeforces Round 920 (Div. 3) F题 根号分治,后缀和,后缀和的后缀和,CF,算法

如图,这是几组后缀和,你会发现他们加起来后,第几个位置就是几倍的那个数。

看不懂看这个理解一下:

(黑线就是这串后缀数)

(比如我们把他们全部加起来,正好第六个数就加了6次,就是乘了k)

Codeforces Round 920 (Div. 3) F题 根号分治,后缀和,后缀和的后缀和,CF,算法

后缀和的后缀和的中间段如何求:

然后就是中间段Codeforces Round 920 (Div. 3) F题 根号分治,后缀和,后缀和的后缀和,CF,算法这个如何求呢? 

不是直接用后缀和的后缀和去减后缀和的后缀和,这样减完是“平行”的,后面的没有被消掉:

Codeforces Round 920 (Div. 3) F题 根号分治,后缀和,后缀和的后缀和,CF,算法(斜线就代表后缀和的后缀和

比如下图我们用a的减去b的,只减了“X”部分,而“O”部分没有被减去:

 Codeforces Round 920 (Div. 3) F题 根号分治,后缀和,后缀和的后缀和,CF,算法

不过显而易见,需要减得“O”部分是平行的,即减去他们正常后缀和的某个倍数即可。

我们算b需要减几倍即可:

这里中间段其实是a到b-1,b-1就是第k个数了。那么下一个数的后缀和的后缀和是k+1倍。不过我们减去 1被了,所以还需要减去k倍。

即后面的数都要减k倍。

————

根号分治:

单纯后缀和也过不了,因为当间隔足够大时(这里是根号n,即sqrt(n)),暴力就足够快啦,反而在数组中记录后缀和会浪费空间。(比如间隔n个,那就一个数放一个位置;间隔n-1个也就第一个数不是自己,这就没必要用后缀和啦,暴力就可以)

所以我们求后缀和只求到间隔为sqrt(n)就好啦。文章来源地址https://www.toymoban.com/news/detail-794835.html

核心代码:

#define ll long long
const ll inf = 1e9;
void solve()
{
	int n, q; cin >> n >> q;
	vector<ll>arr(n + 1);
	for (int i = 1; i <= n; i++)//从1开始。。
		cin >> arr[i];
	//
	//隔d的后缀和 // 把这些后缀和加起来 -> 逐项升数目的后缀和
	int nsqrt = sqrt(n);
	vector<vector<ll>>tarr(nsqrt + 1,vector<ll>(n + 1)), tkarr(nsqrt + 1, vector<ll>(n+1));
	for (int i = 1; i <= nsqrt; i++)
	{
		for (int j = n; j >= 1; j --)
		{
			tarr[i][j] = arr[j]+(j + i > n ? 0:tarr[i][j+i]);
		}
	}
	for (int i = 1; i <= nsqrt; i++)
	{
		for (int j = n; j >= 1; j --)
		{
			tkarr[i][j] = tarr[i][j] + (j + i > n ? 0 : tkarr[i][j + i]);
		}
	}

	for (int i = 1; i <= q; i++)
	{
		int s, d, k;
		cin >> s >> d >> k;
	
		if (d<=nsqrt)
		{
			cout << tkarr[d][s] - (s+d*k>n?0:tkarr[d][s+d*k] + tarr[d][s + d*k]*k)  << " ";
		}
		else
		{
			//暴力
			ll sum = 0;
			for (ll j = 1; j <= k && s <= n; j++)
			{
				sum += arr[s] * j;
				s += d;
			}
			cout << sum << " ";
		}
	}

到了这里,关于Codeforces Round 920 (Div. 3) F题 根号分治,后缀和,后缀和的后缀和的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Codeforces Round 882 (Div. 2)

    目录 A. The Man who became a God  题目分析: B. Hamon Odyssey 题目分析: C. Vampiric Powers, anyone? 题目分析:  n个人分成k组,每一组的力量都是 这样的,那么如果分成k组那么就会有k-1个力量不被统计,将力量总和减去前k-1个最大的力量就是最小的结果   将数组分组,每个组内进行按位与

    2024年02月05日
    浏览(44)
  • Codeforces Round 926 (Div. 2)

    类似于倍投法,就是在一赔一的情况下,第一次压一块钱,每输一次就押注上一次两倍的金额. 假如资金无限的话,这种方法赢的期望为无穷大.原理类似于二进制,不论你输再多次,只要赢一次总额就增加了1.比如 15 二进制1111,前3把一直输,但是只要第4把赢,就一定可以增加 1

    2024年02月20日
    浏览(39)
  • Codeforces Round 868 Div 2

    要求构造一个仅包含 (1) 和 (-1) 的长度为 (n) 的数组 (a) ,使得存在 (k) 个下标对 ((i, j), i j) 满足 (a_i times a_j = 1) 。 当有 (x) 个 (1) , (y) 个 (-1) 时,其满足条件的下标对数量为 (frac{x (x - 1)}{2} + frac{y (y - 1)}{2}) 。 由于 (n) 只有 (100) ,直接枚举 (x) 即可。

    2024年02月01日
    浏览(37)
  • Codeforces Round 881 (Div. 3)

    给定一个数组,给每个元素涂色。求最大的代价。 代价为每个颜色的代价和。 每个颜色的代价为涂了该颜色的元素的极差。 因为是极差,每个元素要么对答案有正的贡献,要么有负的贡献,要么无贡献。且正负贡献的个数要相同。 因为要最大值,自然就是想有正贡献的是最

    2024年02月09日
    浏览(37)
  • Codeforces Round 866 (Div. 2)

    给出一个仅由_或^组成的字符串,你可以在任意位置添加_或^字符,使得字符串满足: 任意字符要么属于^_^的一部分,要么属于^^的一部分。求最少添加的字符数量。 对于_我们只需处理没有组成^_^的_: ①如果_在首位置且左边没有^则添加^ ②如果_在尾位置且右边没有^则添加

    2023年04月25日
    浏览(49)
  • Codeforces Round 912 (Div. 2)

    大等于2依据冒泡排序即可排序,因此判断下1即可 对每一个数字找哪一位肯定为0填0其他的填1 从后往前考虑加到当前集合或新立一个集合 从最高位开始考虑能否为1,计算能否时每个数当前位为1

    2024年02月04日
    浏览(38)
  • Codeforces Round 871 (Div. 4)

    给定n个长度为10的字符串,问其与codeforces字符串的对应下标字母不同的个数。 对于每个字符串从前往后依次和“codeforces”对应字符比较然后统计不同字母数即可 给定长度为n的数组,问连续相邻为0的最大长度 维护一个全局最大长度res,和当前连续序列的长度cnt。从前往后扫

    2024年02月03日
    浏览(47)
  • Codeforces Round 894 (Div. 3)

    签到题 a数组里,大于等于前一个值的a[i]会被写到b里。直接遍历b,如果b[i]比前一个小就在它前面插一个相等的值 计算反过来的长度,判断是否相等就行 对于没有重复口味的集合,能选出的方案是n*(n-1)/2 (从n个里面选2个的组合数)。二分找出需要多少不同口味的冰淇淋,

    2024年02月11日
    浏览(38)
  • Codeforces Round 874 (Div. 3)

    用最少的长度为2的字符串按一定规则拼出s。规则是:前一个字符串的尾与后一个字符串的首相同。 统计s中长度为2的不同字符串数量。 给定数组a[n]和b[n],重排b后,令任意|ai−bi|≤k成立(1≤k≤n)数据保证一定有解。 将a和b分别按从小到大的顺序匹配便是最优的,一定能满足

    2024年02月05日
    浏览(31)
  • Codeforces Round 858 (Div. 2)题解

    目录 A. Walking Master(贪心) 题面翻译 思路: 代码实现  B. Mex Master(贪心) 题面翻译: 思路: 代码实现 C. Sequence Master(数学) 题面翻译: 思路: 代码实现 YunQian is standing on an infinite plane with the Cartesian coordinate system on it. In one move, she can move to the diagonally adjacent point on the

    2023年04月08日
    浏览(74)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包