【xsy2504】farm 容斥原理

题目大意:给你三个数n,m,s,满足n,m,s1018且最大质因数均不大于106

问你存在多少个整数k,满足0km,且(k,0)(0,n)(x,y)组成的三角形面积为s,其中x,y均为整数。

同时,问你存在多少个整数p,满足0p<n,且(0,0)(0,p)(x,y)组成的三角形面积为s,其中x,y均为整数。

请输出两个问题的和。

不超过1000组数据。

 

对于第一个问题,我们列出三角形面积的式子

 

s=(s黄+s灰+s蓝+s红)-s灰-s红-s蓝

s=|12nk12x(ny)xy12y(kx)|

经过化简,有|k(yn)+nx|=2s

若方程有整数解,则有gcd(k,n)|2s

 

我们设N[i]表示数字n中出现了多少个质因数p[i],K[i],S[i]同理。

N[i]>S[i],那么有K[i]S[i]

基于这个性质,我们就可以通过容斥原理来求了,详见代码。

 

考虑第二个问题,第二个问题显然是求s的约数个数,随便搜一下就可以了。

时间复杂度:O(216+σ(1018))

 

 

复制代码
 1 #include<bits/stdc++.h>
 2 #define MM 1000005
 3 #define NN 80000
 4 #define L long long
 5 using namespace std;
 6 
 7 L pow_mod(L x,L k){L ans=1; for(;k;k>>=1,x=x*x) if(k&1) ans=ans*x; return ans;}
 8 
 9 int pri[MM]={0},b[MM]={0},use=0,last[MM]={0},id[MM]={0};
10 void init(){
11     for(int i=2;i<MM;i++){
12         if(!b[i]) pri[++use]=i,last[i]=1,id[i]=use;
13         for(int j=1;j<=use&&i*pri[j]<MM;j++){
14             b[i*pri[j]]=1; last[i*pri[j]]=i;
15             if(i%pri[j]==0) break;
16         }
17     }
18 }
19 
20 int M[NN]={0},N[NN]={0},S[NN]={0};
21 L a[MM]={0},m,n,s,ans=0,hh=0;
22 
23 void rd(L &res,int cnt[]){
24     res=1;
25     for(int i=0;i<3;i++){
26         int x; scanf("%d",&x);
27         for(res*=x;x>1;x=last[x])
28         cnt[id[x/last[x]]]++;
29     }
30 }
31 void dfs(L x,L id){
32     if(id==hh)
33     return void(ans+=(x<=n));
34     int ID=a[id];
35     for(int i=0;i<=S[ID];i++){
36         dfs(x,id+1);
37         x=x*pri[ID];
38     }
39 }
40 void solve(){
41     memset(M,0,sizeof(M)); memset(N,0,sizeof(N)); memset(S,0,sizeof(S)); ans=hh=0;
42     rd(n,N); rd(m,M); rd(s,S);
43     s<<=1; S[1]++;
44     for(int i=0;i<NN;i++) if(N[i]>S[i]) a[hh++]=pow(pri[i],S[i]+1);
45     for(int i=0;i<(1<<hh);i++){
46         L mul=1,zf=1;
47         for(int j=0;j<hh;j++) 
48         if(i&(1<<j)){
49             mul=mul*a[j]; zf=-zf;
50         }
51         ans=ans+(m/mul)*zf;
52     }
53     hh=0; for(int i=0;i<NN;i++) if(S[i]) a[hh++]=i;
54     dfs(1,0);
55     printf("%lld\n",ans);
56 }
57 
58 int main(){
59     init();
60     int t; cin>>t;
61     while(t--) solve();
62 }
复制代码

 

posted @   AlphaInf  阅读(163)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
历史上的今天:
2018-03-19 【2018北京集训6】Lcm DFT&FWT
点击右上角即可分享
微信分享提示