Luogu P6042 「ACOI2020」学园祭 题解

Luogu P6042 「ACOI2020」学园祭 题解

题目描述

定义:

F(0)=1,F(n)=nAij=F(i)F(j)

i=1nj=1ik=1jgcd(Aijj×F(j),Ajkk×F(k))

Solution

式子看起来挺花里胡哨的,把里面的东西简单展开一下其实就是求

i=1nj=1ik=1jgcd((ij)!,(jk)!)i=1nj=1ik=1jmin(ij,jk)!

遇到多个求和号在一起有很多突破的方向,这里选择考虑贡献。

这个 min 似乎很难搞,但是终究是对若干个阶乘求和,则考虑对于一个 d ,计算 d! 的贡献,容易发现 d[1,n12]内。

上面那个式子放在数轴上考虑,其实就是取出两个连在一起的区间 [k,j],[j,i],答案加上这两个区间较短区间的长度的阶乘。(这里的区间长度为右端点减左端点,即所求式子中的形式,后同)

把这两个区间合并成一个区间 [k,i],因为较短的区间长度为 d,则 [k,i] 长度至少为 2d

[k,i] 的长度 len=2d 时没有区别,当 len>2d 时较短区间在左侧或右侧都可以。

那么就可以写出答案的式子:

d=1n12d!(len=2d+1ni=1nlen2+i=1n2d1)

d,len 均为上文定义,i 是枚举的大区间的左端点,也就是上文中 [k,i]k

后面的括号的左半部分是 len>2d 时的贡献次数,右半部分是 len=2d 时的贡献次数。

化简一下:

d=1n12d!(2len=2d+1n(nlen)+(n2d))d=1n12d!(len=0n2dlen+(n2d))d=1n12d!(2×(n2d)(n2d1)2+(n2d))d=1n12d!(n2d)2

最后这个东西长的十分好看,事实上也很好求,把里面的完全平方式展开一下:

n2d=1n12d!nd=1n12d!d+d=1n12d!4d2

发现里面三个求和号都能在 O(n) 的复杂度内预处理,预处理后直接计算即可。

时间复杂度 O(maxn+T)

#include<iostream>
#include<cstdio>
#define ll long long 
const ll mod = 10086001;
template <typename T> T Max(T x, T y) { return x > y ? x : y; }
template <typename T> T Min(T x, T y) { return x < y ? x : y; }
template <typename T> T Add(T x, T y) { return (x + y > mod) ? (x + y - mod) : (x + y); }
template <typename T> T Mod(T x) { return (x >= mod) ? (x - mod) : x; }
template <typename T>
T& read(T& r) {
	r = 0; bool w = 0; char ch = getchar();
	while(ch < '0' || ch > '9') w = ch == '-' ? 1 : 0, ch = getchar();
	while(ch >= '0' && ch <= '9') r = r * 10 + (ch ^ 48), ch = getchar();
	return r = w ? -r : r;
}
const int N = 1000100;
ll fac[N], f1[N], f2[N], f3[N];
int T, n[N], mx;
signed main() {
	read(T);
	for(int i = 1; i <= T; ++i) mx = Max(mx, read(n[i]));
	fac[0] = f1[0] = 1;
	for(int i = 1; i <= mx; ++i)
		fac[i] = fac[i-1] * i % mod,
		f1[i] = Add(f1[i-1], fac[i]),
		f2[i] = Add(f2[i-1], fac[i] * 4 * i % mod),
		f3[i] = Add(f3[i-1], fac[i] * 4 * i % mod * i % mod);
	for(int i = 1; i <= T; ++i) {
		int m = (n[i]-1)/2;
		printf("%lld\n", Add(Mod(1ll * n[i] * n[i] % mod * f1[m] % mod - n[i] * f2[m] % mod + mod), f3[m]));
	}
	return 0;
}
posted @   do_while_true  阅读(63)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?

This blog has running: 1845 days 1 hours 33 minutes 50 seconds

点击右上角即可分享
微信分享提示