闲话 22.12.26

闲话

下一个目标就是 LP!
我觉得在闲话里写这种东西有奇效呢(
上次也是 上上次也是
抄书会被干吗?

我不知道啊 我反正只看从网上找到的资料

模拟赛 T2 O(n)?这种东西不算不闲的闲话吧
答案肯定是 [1, x - 1] * [x, y] 或 [x, y] * [y + 1, n] 的更大值
这启发我们固定 len,在后缀链接树上合并 endpos,记录 max/min
假设 min = max 这个点只有一个 endpos
反之 min < max,我们取 [min, min + len - 1] [max, max + len - 1] 都可以作为 [x, y]
判 max - min >= len 算答案
就没了
你可能会问
就是可能目前的 len 不是最优的
可能这部分长 那部分短
但是发现 len 是连续的
所以答案最优

类欧几里得算法

【模板】类欧几里得算法

Euclidean?

我们一个一个说。

1. f(a,b,c,n)

f(a,b,c,n)=i=0nai+bc

我们分情况讨论。

首先预处理一下。当 acbc 时我们能将其对 c 取模:

 f(a,b,c,n)= i=0nai+bc= i=0n(acc+amodc)i+(bcc+bmodc)c= i=0nacci+bcc+(amodc)i+bmodcc= i=0nacci+bccc+i=0n(amodc)i+bmodcc= acn(n+1)2+bc(n+1)+i=0n(amodc)i+bmodcc= acn(n+1)2+bc(n+1)+f(amodc,bmodc,c,n)

然后我们可以假定 a,b<c 了。考虑转化贡献:

 f(a,b,c,n)= i=0nai+bc= i=0nj=1ai+bc1= j=1an+bci=0n[jai+bc]= j=1an+bci=0n[jai+bc]= j=1an+bci=0n[jcb1<ai]= j=1an+bci=0n[jcb1a<i]= j=1an+bc(njcb1a)= nan+bcj=0an+bc1jc+cb1a

m=an+bc,我们有

f(a,b,c,n)=nmf(c,cb1,a,m1)

这两个式子共同的地给出了类似于辗转相除法的做法,因此复杂度为 O(logn)。这也是该算法名称的来源。

2. g(a,b,c,n)

同理,有

 g(a,b,c,n)= i=0niai+bc= i=0ni(acc+amodc)i+(bcc+bmodc)c= i=0niacci+bcc+(amodc)i+bmodcc= i=0niacci+bccc+i=0ni(amodc)i+bmodcc= acn(n+1)(2n+1)2+bcn(n+1)2+i=0ni(amodc)i+bmodcc= acn(n+1)(2n+1)2+bcn(n+1)2+g(amodc,bmodc,c,n)

m=an+bc。同理,有

 g(a,b,c,n)= i=0niai+bc= i=0nj=1ai+bci= j=1mi=0ni[jai+bc]= j=1mi=0ni[jai+bc]= j=1mi=0ni[jcb1<ai]= j=0m1i=0ni[jc+cb1a<i]

t=jc+cb1a,有

j=0m1i=0ni[t<i]= j=0m1(nt)(n+t+1)2= 12(m(n2+n)j=0m1(t2+t))= 12(m(n2+n)h(c,cb1,a,m1)f(c,cb1,a,m1))

3. h(a,b,c,n)

同理,有

 h(a,b,c,n)= i=0nai+bc2= i=0n(acc+amodc)i+(bcc+bmodc)c2= i=0nacci+bcc+(amodc)i+bmodcc2= i=0nacci+bccc2+i=0n(amodc)i+bmodcc2+2i=0nacci+bccc×(amodc)i+bmodcc2= i=0n(aci+bc)2+i=0n(amodc)i+bmodcc2+2i=0n(aci+bc)×(amodc)i+bmodcc= i=0n(ac2i2+bc2+2acbci)+h(amodc,bmodc,c,n)+2aci=0ni(amodc)i+bmodcc+2bci=0n(amodc)i+bmodcc= ac2n(n+1)(2n+1)2+bc2(n+1)+acbcn(n+1)+h(amodc,bmodc,c,n)+2acg(amodn,bmodn,c,n)+2bcf(amodn,bmodn,c,n)

m=an+bc,t=jc+cb1a

我们不想出现两个求和号相乘,因此拆开 n22n(n+1)/2n

 f(a,b,c,n)= i=0nai+bc2= i=0n(2j=1ai+bcjai+bc)= 2i=0nj=1ai+bcjf(a,b,c,n)

i=0nj=1ai+bcj= j=0m1(j+1)i=0n[j<ai+bc]= j=0m1(j+1)i=0n[i>t]= j=0m1(j+1)(nt)= nm(m+1)2j=0m1(j+1)t= nm(m+1)2j=0m1jtj=0m1t= nm(m+1)2g(c,cb1,a,m1)f(c,cb1,a,m1)

h(a,b,c,n)=nm(m+1)2g(c,cb1,a,m1)2f(c,cb1,a,m1)f(a,b,c,n)

我们可以将三个函数合并递归,这样减小了常数。

根据辗转相除法,总时间复杂度为 O(logn)

合并写法
int T, n, a, b, c;
struct dat {
	mint f, g, h;
};

dat f(int n, int a, int b, int c) {
	mint ac = a / c, bc = b / c, m = (1ll * a * n + b) / c, n1 = n + 1, n21 = 2 * n + 1;
	dat ret;
	if (a == 0) {
		ret.f = bc * n1, ret.g = bc * n * n1 * inv2, ret.h = bc * bc * n1;
		return ret;
	}
	if (a >= c or b >= c) {
		ret.f = n * n1 * inv2 * ac + bc * n1;
		ret.g = ac * n * n1 * n21 * inv6 + bc * n * n1 * inv2;
		ret.h = ac * ac * n * n1 * n21 * inv6 + 
				bc * bc * n1 + ac * bc * n * n1;

		auto v = f(n, a % c, b % c, c);

		ret.h += v.h + 2 * bc * v.f + 2 * ac * v.g;
		ret.g += v.g;
		ret.f += v.f;
		return ret;
	} 
	auto v = f((1ll * a * n + b) / c - 1, c, c - b - 1, a);
	ret.f = n * m - v.f;
	ret.g = inv2 * (n * m * n1 - v.h - v.f);
	ret.h = n * m * (m + 1) - 2 * v.g - 2 * v.f - ret.f;
	return ret;
}

signed main() {
	iot;
	cin >> T;
	while ( T -- ) {
		cin >> n >> a >> b >> c;
		auto v = f(n, a, b, c);
		cout << v.f << ' ' << v.h << ' ' << v.g << '\n';
	}
}
posted @   joke3579  阅读(79)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示