提高培优班D14T4简单三元组计数题解

提高培优班 D14T4 简单三元组计数题解

题意简述

已知 l,r , 求 \underset {l\le i<j<k\le r}\Sigma lcm(i,j,k)\ge i+j+k

思路

正难则反

\underset {l\le i<j<k\le r}\Sigma lcm(i,j,k)\ge i+j+k\to tot-\underset {l\le i<j<k\le r}\Sigma lcm(i,j,k)< i+j+k

\because i+j+k<3k\ and\ k\mid lcm(i,j,,k)

\therefore lcm(i,j,k)=k\ or\ lcm(i,j,k)=2k \ \ \ \ \alpha

显然,枚举 k 复杂度错误。

lcm(i,j,k)=x,i=\frac{x}{a},j=\frac{x}{b},k=\frac{x}{c}

\frac{1}{a}+\frac{1}{b}+\frac{1}{c}>1,a>b>c

\alpha 得, c=1/2

考虑 c=2 的情况,

易得出,只有 \begin{cases}a=4\\b=3\\c=2\end{cases} \begin{cases}a=5\\b=3\\c=2\end{cases} 满足情况。

那么可以得出,$i:j:k=3:4:6/6:10:15$

这样数数就很简单了

再考虑 c=1 的情况,

显然,此时 i,j\mid k

cnt_i 表示 i[l,r] 中,约数个数(不含 i )

则答案为 \Sigma C_{cnt_i}^2

这里我们可以直接考虑离线,从 max\_r 开始倒取,给 i 的倍数 +1 即可

单点修改,区间查值,就是树状数组板子。

code

#define int long long
const int N=2e5+5000;
int cnt[N],t[N],ans[N],maxr;
vector<pair<int,int> >e[N];
inline int calc(int a){return a*(a-1)/2*(a-2)/3;}
inline void add(int x,int d){for(;x<=maxr;x+=x&-x)t[x]+=d;}
inline int ask(int x){int ret=0;for(;x;x^=x&-x)ret+=t[x];return ret;}
signed main(){
	int T;read(T);
	for(int i=1,l,r;i<=T;i++){
		read(l,r);
        ans[i]=calc(r-l+1)-max(0ll,r/6-(l+2)/3+1)-max(0ll,r/15-(l+5)/6+1);
		e[l].emplace_back(make_pair(i,r));maxr=max(maxr,r);
	}for(int i=maxr;i;i--){
		for(int j=i<<1;j<=maxr;j+=i) add(j,cnt[j]++);//log^2 n
		for(pair<int,int> v:e[i]) ans[v.first]-=ask(v.second)-ask(i-1);
	}
	for(int i=1,l,r;i<=T;i++) printf("%lld\n",ans[i]);
	return 0;
}

\LaTeX 修一下

image