「万能欧几里得」学习笔记

一直以为这个是计数内容

第一次看见是在 djq 的论文里,还以为是新东西( ,不过我确实还没学就是了。

称之为欧几里得的东西,想必一定利用 modswap 达到了 log 复杂度的目的。
这种数形结合的形式还真是有趣呢


所谓万能欧几里得,是解决这样一种问题的:

在平面直角坐标系上的一次函数 y=Px+RQ,从 x=0 扫到 x=L ,每次若直线碰到横线就执行 U ,如果碰到竖线就执行 R ,其中 U,R 是指两个具有结合律的操作,钦定经过整点时先执行 U

Step 1. PmodQ

y=Px+RQ=PQx+(PmodQ)x+RQ

PQ ,则在每个 R 前一定至少有 PQU ,那么把 PQUR 拼到一起,有 f(P,Q,R,L,U,R)=f(PmodQ,Q,R,L,U,UPQR)

Step 2. swap(P,Q)

不就是对称翻转嘛

将原本的函数以 y=x 为对称轴翻转,也就是 y=Px+RQ 变成了 y=QxR1P ,具体推导是设第 aR 在第 bU 之前,列出式子然后调整一下取整函数。
这样的推导同时也保证了操作的优先级正确。

几个问题:

  1. R1<0
  2. 原本 x=L 的地方可能 y 不是整数。

针对第一个问题,由于我们知道 P<Q,R<Q ,所以 QR10 ,也即 x=1 处取值一定为正,那么把这前面一段先计算了放在前面就行。
嗯这里提到了 R<Q ,原因是如果 RQ 那我们完全可以将其直接提出常数个 U

针对第二个问题,也是把后面的一段另外计算即可,知道了总共有多少个 UR ,算这个还是很简单的。


实际应用时要注意 U,R 表示成多元组形式的结合。

应用于类欧模板(省去 includedefine):
(高度拟合pb)

using namespace std;
typedef long long ll;
const int mod=998244353;
int T,n,a,b,c;
struct node{
	int a,b,s1,s2,s3;
	node(){a=b=s1=s2=s3=0;}
	node(int A,int B,int C,int D,int E){a=A;b=B;s1=C;s2=D;s3=E;}
	friend inline node operator*(node f,node g){
		node ret;
		ret.a=add(f.a,g.a);
		ret.b=add(f.b,g.b);
		ret.s1=((ll)f.a*g.b + f.s1 + g.s1) % mod;
		ret.s2=((ll)f.a*f.a%mod*g.b%mod + 2ll*f.a*g.s1%mod + f.s2 + g.s2) % mod;
		ret.s3=(((ll)f.a * g.b + g.s1) % mod * f.b % mod + (ll)g.b*(g.b+1)/2 % mod * f.a % mod + f.s3 + g.s3 ) % mod;
		return ret;
	}
}U,R,I;
node power(node x,int n){
	node a;
	while(n){
		if(n&1)a=a*x;
		x=x*x;
		n>>=1;
	}
	return a;
}
node f(int P,int Q,int R,ll L,node a,node b){
	if(!L)return node();
	if(!(((ll)L*P+R)/Q))return power(b,L);
	if(P>=Q)return f(P%Q,Q,R,L,a,power(a,P/Q)*b);
	// if(!P)return node(0,L,0,0,0);
	node ret=power(b,(Q-R-1)/P)*a;
	ll len=((ll)L*P+R)/Q;
	ret=ret*f(Q,P,(Q-R-1)%P,len-1,b,a);
	ret=ret*power(b,L-((ll)len*Q-R-1)/P);
	return ret;
}
int main(){
	freopen("data.in","r",stdin);
	freopen("data.out","w",stdout);
	U.a=R.b=1;
	scanf("%d",&T);
	while(T--){
		scanf("%d%d%d%d",&n,&a,&b,&c);
		I.a=b/c;
		node ans=f(a,c,b%c,n,U,R);
		ans=node(b/c,0,0,0,0)*ans;
		printf("%d %d %d\n",add(ans.s1,(b/c))%mod,((ll)(b/c)*(b/c)+ans.s2)%mod,ans.s3);
	}

	return 0;
}
posted @   Kelvin2005  阅读(74)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示