易语言如何做网站钦州建设网站
news/
2025/9/30 20:05:18/
文章来源:
易语言如何做网站,钦州建设网站,网络营销常见的推广方式,美克美家网站建设题目
给定长为n(n2e5)的1-n的排列p#xff0c;
求(i,j)(1ijn)对的数量#xff0c;满足gcd(i,j)≠1且gcd(pi,pj)≠1
思路来源
官方题解
题解 参考莫比乌斯函数mu#xff0c;定义一个新函数#xff0c;
新函数需要满足n1的时候对因子求和为0#xff0…题目
给定长为n(n2e5)的1-n的排列p
求(i,j)(1ijn)对的数量满足gcd(i,j)≠1且gcd(pi,pj)≠1
思路来源
官方题解
题解 参考莫比乌斯函数mu定义一个新函数
新函数需要满足n1的时候对因子求和为0大于1的时候对因子求和为1
就能将gcd(i,j)≠1展开为新函数了 然后发现实际上就是
之前n2的时候因子mu之和为0
由于gcd不能为1要忽略mu[1]的贡献
那么0减掉mu[1]之后是-1取反之后即为1
所以相当于把之前奇偶因子的符号取反 枚举i和i的倍数j所有倍数j需要反演得到i固定时的答案
此时这些j已经满足gcd(j1,j2)≠1第二个条件需要再套一次反演
把这些pj塞入vector再做一次反演即可 一共有x个数时任意取两个可以重复取
等价于有x个数和一个空位这x1个数取两个
取到了一个数和一个空位的时候就认为是取了两次相同的数
代码1容斥
#include bits/stdc.h
#includeiostream
#includecstdio
#includevector
#includemap
using namespace std;
#define rep(i,a,b) for(int i(a);i(b);i)
#define per(i,a,b) for(int i(a);i(b);--i)
typedef long long ll;
typedef double db;
typedef pairint,int P;
#define fi first
#define se second
#define pb push_back
#define dbg(x) cerr(#x):x ;
#define dbg2(x) cerr(#x):xendl;
#define SZ(a) (int)(a.size())
#define sci(a) scanf(%d,(a))
#define pt(a) printf(%d,a);
#define pte(a) printf(%d\n,a)
#define ptlle(a) printf(%lld\n,a)
#define debug(...) fprintf(stderr, __VA_ARGS__)
const int N2e510;
int n,p[N],a[N];
vectorintfac[N],tmp;
mapint,llbs;
ll dp[N],f[N],res;
//x内任取两个 gcd大于1的(i,j)方案数
ll cal(vectorintx){bs.clear();for(auto v:x){for(auto d:fac[v]){bs[d];}}int c0;for(auto x:bs){x.se1ll*x.se*(x.se1)/2;a[c]x.fi;f[x.fi]x.se;}ll ans0;//printf(c:%d v:%d\n,c,a[1]);per(i,c,1){int va[i];if(v1)break;ll wf[v];for(auto d:fac[v]){f[d]-w;}answ;}return ans;
}
int main(){sci(n);rep(i,1,n)sci(p[i]);rep(i,1,n){for(int ji;jn;ji){fac[j].pb(i);}}per(i,n,2){tmp.clear();for(int ji;jn;ji){tmp.pb(p[j]);}dp[i]cal(tmp);//printf(i:%d dp1:%lld\n,i,dp[i]);for(int j2*i;jn;ji){dp[i]-dp[j];}//printf(i:%d dp2:%lld\n,i,dp[i]);resdp[i];}printf(%lld\n,res);return 0;
}
代码2反演
//#include bits/stdc.h
#includeiostream
#includecstdio
#includevector
#includemap
using namespace std;
#define rep(i,a,b) for(int i(a);i(b);i)
#define per(i,a,b) for(int i(a);i(b);--i)
typedef long long ll;
typedef double db;
typedef pairint,int P;
#define fi first
#define se second
#define pb push_back
#define dbg(x) cerr(#x):x ;
#define dbg2(x) cerr(#x):xendl;
#define SZ(a) (int)(a.size())
#define sci(a) scanf(%d,(a))
#define pt(a) printf(%d,a);
#define pte(a) printf(%d\n,a)
#define ptlle(a) printf(%lld\n,a)
#define debug(...) fprintf(stderr, __VA_ARGS__)
const int N2e510;
int n,p[N],a[N],mu[N];
vectorintfac[N],tmp;
ll dp[N],bs[N],f[N],res;
//x内任取两个 gcd大于1的(i,j)方案数
ll cal(vectorintx){for(auto v:x){for(auto d:fac[v]){if(!mu[d])continue;bs[d];}}ll ans0;for(auto v:x){for(auto d:fac[v]){if(!bs[d] || d1 || !mu[d])continue;bs[d]1ll*bs[d]*(bs[d]1)/2;ans-mu[d]*bs[d];bs[d]0;}}return ans;
}
int main(){sci(n);rep(i,1,n)sci(p[i]);mu[1]1;rep(i,1,n){fac[i].pb(i);for(int j2*i;jn;ji){mu[j]-mu[i];fac[j].pb(i);}}per(i,n,2){if(!mu[i])continue;tmp.clear();for(int ji;jn;ji){tmp.pb(p[j]);}dp[i]cal(tmp);res-mu[i]*dp[i];//printf(i:%d dp1:%lld\n,i,dp[i]);// for(int j2*i;jn;ji){// dp[i]-dp[j];// }// //printf(i:%d dp2:%lld\n,i,dp[i]);// resdp[i];}printf(%lld\n,res);return 0;
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/923216.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!