• 【xsy2504】farm 容斥原理


    题目大意:给你三个数$n,m,s$,满足$n,m,s≤10^{18}$且最大质因数均不大于$10^6$。

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

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

    请输出两个问题的和。

    不超过1000组数据。

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

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

    $s=|frac{1}{2}nk-frac{1}{2}x(n-y)-xy-frac{1}{2}y(k-x)|$

    经过化简,有$|k(y-n)+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(2^{16}+sigma(10^{18}))$

     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
    ",ans);
    56 }
    57 
    58 int main(){
    59     init();
    60     int t; cin>>t;
    61     while(t--) solve();
    62 }
  • 相关阅读:
    Smobiler如何实现.net一键开发,ios和android跨平台运行
    使用Smobiler实现类似美团的界面
    疫情当下,企业系统如何快速实现移动化?
    Smobiler针对百度文字识别SDK动态编译与运行
    smobiler自适应不同手机分辨率
    仓库管理移动应用解决方案——C#开发的移动应用开源解决方案
    移动OA办公——Smobiler第一个开源应用解决方案,快来get吧
    react-native 标题随页面滚动显示和隐藏
    react-native 键盘遮挡输入框
    解决adb网络连接中出现的“由于目标计算机积极拒绝,无法连接”错误
  • 原文地址:https://www.cnblogs.com/xiefengze1/p/10556490.html
Copyright © 2020-2023  润新知