BZOJ1220 HNOI2002 跳蚤 【容斥原理+高精度】*

BZOJ1220跳蚤问题解析
本文详细解析了BZOJ1220跳蚤问题,通过容斥原理解决高精度计算问题,提供了完整的代码实现。

BZOJ1220 HNOI2002 跳蚤


Description

Z城市居住着很多只跳蚤。在Z城市周六生活频道有一个娱乐节目。一只跳蚤将被请上一个高空钢丝的正中央。钢丝很长,可以看作是无限长。节目主持人会给该跳蚤发一张卡片。卡片上写有N+1个自然数。其中最后一个是M,而前N个数都不超过M,卡片上允许有相同的数字。跳蚤每次可以从卡片上任意选择一个自然数S,然后向左,或向右跳S个单位长度。而他最终的任务是跳到距离他左边一个单位长度的地方,并捡起位于那里的礼物。比如当N=2,M=18时,持有卡片(10, 15, 18)的跳蚤,就可以完成任务:他可以先向左跳10个单位长度,然后再连向左跳3次,每次15个单位长度,最后再向右连跳3次,每次18个单位长度。而持有卡片(12, 15, 18)的跳蚤,则怎么也不可能跳到距他左边一个单位长度的地方。当确定N和M后,显然一共有MN张不同的卡片。现在的问题是,在这所有的卡片中,有多少张可以完成任务。

Input

输入文件有且仅有一行,包括用空格分开的两个整数N和M。

Output

输出文件有且仅有一行,即可以完成任务的卡片数。 1≤M≤108,1≤N≤M,1≤M≤10^8,1≤N≤M,1M1081NMMN≤1016M^N≤10^{16}MN1016。(注意:这个数据范围是错的,此题需要高精度。)

Sample Input

2 4

Sample Output

12

HINT

此题需要高精度!


我们考虑有解的情况是什么
就是对于所有的i∈[1,n]i\in[1,n]i[1,n]的gcd和m互质
直接统计不好搞,就可以用容斥的思想
考虑所有解减去不合法的解
那么如何考虑减去不合法解呢?
考虑容斥一下,累加最大公约数是i的方案数
然后对于i的容斥系数是(−1)i的质因子数(-1)^{i的质因子数}(1)i
所以对于每个i的贡献是((mi)n(−1)i的质因子数)((\frac{m}{i})^n(-1)^{i的质因子数})((im)n(1)i)
前面一部分的意思是每个位置都可以选择i的倍数的方案数,这也是容斥系数的根源所在
for example:
60=2∗2∗3∗560=2*2*3*560=2235
一共有2,3,52,3,52,3,5三个质因子
我们考虑60的贡献
2,3,52,3,52,3,5减去了贡献
2∗3,2∗5,3∗52*3,2*5,3*523,25,35加上了贡献
所以在60处贡献减去(因为考虑的是减去不合法方案)
然后看10的贡献
2,52,52,5减去了贡献
所以在10加上贡献
就很显然了


#include<bits/stdc++.h>
using namespace std;
#define N 1010
#define LL long long
#define fu(a,b,c) for(int a=b;a<=c;++a)
#define fd(a,b,c) for(int a=b;a>=c;--a)
const int Base=10000;
struct Big{
  int len,w,t[N];
  Big(){len=w=1;memset(t,0,sizeof(t));}
}ans;
Big change(int a){
  Big c;c.len=0;
  if(a<0)c.w=-1;
  a=abs(a);
  while(a)c.t[++c.len]=a%Base,a/=Base;
  return c;
}
void print(Big c){
  if(c.w==-1)printf("-");
  printf("%d",c.t[c.len]);
  fd(i,c.len-1,1)printf("%04d",c.t[i]);
  printf("\n");
}
bool unsigned_cmp(Big a,Big b){//只比较数字大小
  if(a.len>b.len)return 1;
  if(a.len<b.len)return 0;
  fd(i,a.len,1){
    if(a.t[i]>b.t[i])return 1;
    if(a.t[i]<b.t[i])return 0;
  }
  return 1;
}
Big unsigned_add(Big a,Big b){
  Big c;c.len=max(a.len,b.len);
  fu(i,1,c.len)c.t[i]=a.t[i]+b.t[i];
  fu(i,1,c.len){
    if(c.t[i]>Base){
      c.t[i]-=Base;
      c.t[i+1]++;
      if(i==c.len)c.len++;
    }
  }
  return c;
}
Big unsigned_sub(Big a,Big b){
  Big c;c.len=max(a.len,b.len);
  fu(i,1,c.len)c.t[i]=a.t[i]-b.t[i];
  fu(i,1,c.len){
    if(c.t[i]<0){
      c.t[i]+=Base;
      c.t[i+1]--;
    }
  }
  fd(i,c.len,1){
    if(!c.t[i])c.len--;
    else break;
  }
  return c;
}
Big add(Big a,Big b){
  Big c;
  if(unsigned_cmp(b,a))swap(a,b);
  if(a.w==1&&b.w==1)c=unsigned_add(a,b),c.w=1;
  if(a.w==1&&b.w==-1)c=unsigned_sub(a,b),c.w=1;
  if(a.w==-1&&b.w==1)c=unsigned_sub(a,b),c.w=-1;
  if(a.w==-1&&b.w==-1)c=unsigned_add(a,b),c.w=-1;
  return c;
}
Big sub(Big a,Big b){b.w=0-b.w;return add(a,b);}
Big mul(Big a,Big b){
  Big c;c.w=a.w*b.w;
  c.len=a.len+b.len-1;
  fu(i,1,a.len)
    fu(j,1,b.len)
      c.t[i+j-1]+=a.t[i]*b.t[j];
  fu(i,1,c.len){
    if(c.t[i]>Base){
      c.t[i+1]+=c.t[i]/Base;
      c.t[i]%=Base;
      if(i==c.len)c.len++;
    }
  }
  return c;
}
Big fast_pow(Big a,int b){
  Big ans;ans.t[1]=1;
  if((b&1)&&a.w==-1)ans.w=-1;
  while(b){
    if(b&1)ans=mul(ans,a);
    b>>=1;
    a=mul(a,a);
  }
  return ans;
}
int n,m;
int p[N],cnt=0;
bool check(int vl){
  fu(i,2,sqrt(vl))
    if(vl%i==0)return 0;
  return 1;
}
void divide(int num){
  fu(i,2,num){
    if(num%i==0&&check(i)){
      p[++cnt]=i;
      while(num%i==0)num/=i;
    }
  }
}
void dfs(int tmp,LL sum,int typ){
  if(tmp>cnt)return;
  dfs(tmp+1,sum,typ);
  sum*=p[tmp];typ*=-1;
  Big now=change(sum);
  now=fast_pow(change(m/sum),n);
  now.w=typ;
  ans=add(ans,now);
  dfs(tmp+1,sum,typ);
}
int main(){
  scanf("%d%d",&n,&m);
  divide(m);
  ans=fast_pow(change(m),n);
  dfs(1,1ll,1);
  print(ans);
  return 0;
}
内容概要:本文主要介绍了一种基于Matlab实现的交叉小波和小波相干性分析方法,旨在帮助科研人员通过Matlab代码实现信号交叉小波和小波相干性(Matlab代码实现)的时频域联合分析。交叉小波可用于分析两个非平稳信号之间的局部相关性,而小波相干性则进一步揭示它们在不同频率和时间尺度上的相干程度,适用于气象、海洋、生物医学、电力系统等多领域的时间序列数据分析。文中提供了完整的Matlab代码示例,并结合实际应用场景展示其操作流程与结果可视化方式。; 适合人群:具备一定信号处理基础和Matlab编程能力的研究生、科研人员及工程技术人员,尤其适合从事时间序列分析、多变量信号相关性研究的相关领域工作者。; 使用场景及目标:①分析两个时间序列在时频域内的局部相关性和相位关系;②识别信号间的周期性耦合特征,如气候因子关联、脑电/心电信号交互、电力负荷与气象因素的关系等;③通过小波相干图直观展示变量间的动态关联强度与滞后关系,支撑科学决策与机理探究; 阅读建议:建议读者结合Matlab环境实际运行所提供的代码,理解小波变换、交叉小波与小波相干性的数学原理,并尝试将方法迁移至自身研究领域的数据集上进行验证与优化,同时注意参数设置(如小波基函数、边缘效应处理)对结果的影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值