[SDOI2018]旧试题,洛谷P4619,莫比乌斯反演+三元环计数

正题

      突然发现很多SDOI的题

      题目也很直白,要求:\sum_{i=1}^A\sum_{j=1}^B\sum_{k=1}^Cd(ijk)

     后面的d(ijk)=\sum_{x\mid i}\sum_{y\mid j}\sum_{z\mid k} [gcd(x,y)=1][gcd(x,z)=1][gcd[y,z]=1]

     证明可以仿照约数个数和一题。

     然后换进去,就变成\sum_{i=1}^A\sum_{j=1}^B\sum_{k=1}^C\sum_{x\mid i}\sum_{y\mid j}\sum_{z\mid k} \sum_{d_1\mid gcd(x,y)}\mu(d_1)\sum_{d_2\mid gcd(x,z)}\mu(d_2)\sum_{d_3\mid gcd(y,z)}\mu(d_3)

     变形一下:\sum_{d_1=1}^A \sum_{d_2=1}^A\sum_{d_3=1}^B \mu(d_1)\mu(d_2)\mu(d_3)\sum_{lcm(d_1,d_2)\mid x}\frac{A}{x}\sum_{lcm(d_1,d_3)\mid y}\frac{B}{y}\sum_{lcm(d_2,d_3)}\frac{C}{z}

     发现后面是很有规律的,其实就是[1,\frac{A}{lcm(d_1,d_2)}],[1,\frac{B}{lcm(d_1,d_3)}],[1,\frac{C}{lcm(d_2,d_3)}]的约数个数和。

     公式就变成了\sum_{d_1=1}^A \sum_{d_2=1}^A\sum_{d_3=1}^B \mu(d_1)\mu(d_2)\mu(d_3)d(\frac{A}{lcm(d_1,d_2)})d(\frac{B}{lcm(d_1,d_3)})d(\frac{C}{lcm(d_2,d_3)})

     发现,当\mu(d_1),\mu(d_2),\mu(d_3)=0/lcm(d_1,d_2)>A/lcm(d_1,d_3)>B/lcm(d_2,d_3)>C时,这条式子没有贡献。

     那么考虑互不相等的d_1,d_2,d_3。若lcm(x,y)<=max(A,B,C),那么就从x\to y连一条权值为lcm(x,y)的边。

     当然\mu(x),\mu(y)\neq 0

     然后跑一次三元环计数,对于每一个处理出来的三元环,把d_1,d_2,d_3互换的6种情况考虑一遍即可。

     对于相等的d_1,d_2,d_3贡献也是十分明显的,跑一次n循环就可以了。

     对于有一组相等的d_1,d_2,d_3,枚举边,然后互换d_1,d_2,d_3即可。

#include
#include
#include
#include
using namespace std;

struct edge{
	int y,next,c;
}s[2100010];
struct p_edge{
	int x,y,c;
}p[2100010];
const int maxn=1e5;
int T,n,len=0,a,b,c;
int in[maxn+10];
int pi[maxn+10],mu[maxn+10],temp;
long long fa[maxn+10],fb[maxn+10],fc[maxn+10],d[maxn+10];
int first[maxn+10],tf[maxn+10];
bool vis[maxn+10];
long long ans=0,mod=1e9+7;

int gcd(int x,int y){
	if(y==0) return x;
	return gcd(y,x%y);
}

void ins(int x,int y,int c){
	s[++len]=(edge){y,first[x],c};first[x]=len;
}

void prepare(){
	int t1,t2,t3;
	for(int i=1;i<=n;i++) 
		if(mu[i]) ans+=mu[i]*mu[i]*mu[i]*fa[i]*fb[i]*fc[i];
	int tot=0;
	for(int g=1;g<=n;g++)
		for(int i=1;(t1=i*g)<=n;i++){
			if(!mu[t1]) continue;
			for(int j=i+1;(t2=j*g)<=n;j++){
				if(!mu[t2] || gcd(i,j)!=1) continue;
				if(1ll*i*j*g>n) break;
				t3=1ll*i*j*g;
				ans+=mu[t1]*mu[t1]*mu[t2]*(fa[t3]*(fb[t3]*fc[t1]+fb[t1]*fc[t3])+fa[t1]*fb[t3]*fc[t3]);
				ans+=mu[t1]*mu[t2]*mu[t2]*(fa[t3]*(fb[t2]*fc[t3]+fb[t3]*fc[t2])+fa[t2]*fb[t3]*fc[t3]);
				in[t1]++;in[t2]++;p[++tot]=(p_edge){t1,t2,t3};
			}
		}
	for(int i=1;i<=tot;i++)
		if(in[p[i].x]

     

你可能感兴趣的:([SDOI2018]旧试题,洛谷P4619,莫比乌斯反演+三元环计数)