BZOJ4635 : 数论小测验

第一问:

设$a[i]$表示使用$[1,i]$的数字$n$次形成的数组里有多少个$\gcd=1$。

考虑容斥,则$a[i]=i^n-\sum_{j=2}^i a[\lfloor\frac{i}{j}\rfloor]$,可以分$\sqrt{i}$段算出。

$ans=\sum_{i=l}^r a[\lfloor\frac{m}{i}\rfloor]$,也可以分$\sqrt{m}$段算出。

注意到只有$\sqrt{m}$个$a[i]$被使用到,所以只计算它们即可。

时间复杂度$O(m)$。

第二问:

设$s[i][j]$表示$1$到$j$里有多少数字与$i$互质,可以通过$O(m^2)$的预处理求出。

对于一个询问,枚举所有$k$,计算$k|lcm$的答案。

将$k$分解质因数,则使用的$n$个数字相应质因子的指数不能比它小。

考虑容斥,转化成求有多少数字对应指数都比它小。

设$k$的质因子乘积为$mul$,则方案数为$(\sum_{d|\frac{k}{mul}}s[mul][\lfloor\frac{m}{d}\rfloor])^n$。

时间复杂度$O(m\log m)$。

#include<cstdio>
const int N=1001,M=7100,P=1000000007;
int T,type,t,n,m,l,r,i,j;
int f[N][N],s[N][N],G[N],V[M],NXT[M],mul[N],g[N],v[M],nxt[M],ed;
int p[N],a[10000001],b[N],ans;
inline void up(int&a,int b){a+=b;while(a>=P)a-=P;}
inline int pow(int a,int b){int t=1;for(;b;b>>=1,a=1LL*a*a%P)if(b&1)t=1LL*t*a%P;return t;}
inline void init(int x,int n){
  int t=0,i,j;
  for(i=2;i<=x;i=j+1)j=x/(x/i),up(t,1LL*(j-i+1)*a[x/i]%P);
  a[x]=(pow(x,n)+P-t)%P;
}
void dfs(int x,int y,int z){
  if(x==t){
    if(z==1)return;
    mul[y>0?y:-y]=z;
    v[++ed]=y;nxt[ed]=g[i];g[i]=ed;
    return;
  }
  dfs(x+1,y,z),dfs(x+1,-y*a[x],z*b[x]);
}
inline void cal(int x){
  up(ans,p[m]);
  for(int i=g[x];i;i=nxt[i]){
    if(v[i]>0)up(ans,p[a[v[i]]]);
    else up(ans,P-p[a[-v[i]]]);
  }
}
int main(){
  scanf("%d%d",&T,&type);
  if(type==1){
    a[1]=1;
    while(T--){
      scanf("%d%d%d%d",&n,&m,&l,&r);ans=0;
      for(i=1;i<=m;i=m/(m/i)+1)v[++t]=m/i;
      while(t)init(v[t--],n);
      for(i=l;i<=r;i=j+1){
        j=m/(m/i);
        if(j>r)j=r;
        up(ans,1LL*(j-i+1)*a[m/i]%P);
      }
      printf("%d\n",ans);
    }
  }else{
    for(i=0;i<N;i++)f[0][i]=f[i][0]=f[i][i]=i;
    for(i=2;i<N;i++)for(j=1;j<i;j++)f[i][j]=f[j][i]=f[i-j][j];
    for(i=1;i<N;i++)for(j=1;j<N;j++)s[i][j]=s[i][j-1]+(f[i][j]==1);
    for(i=1;i<N;i++)for(j=i;j<N;j+=i)V[++ed]=i,NXT[ed]=G[j],G[j]=ed;
    for(ed=0,i=2;i<N;i++){
      for(n=i,t=0,j=2;j<=n;j++)if(n%j==0){
        for(m=1;n%j==0;n/=j,m*=j);
        a[t]=m,b[t++]=j;
      }
      dfs(0,1,1);
    }
    while(T--){
      scanf("%d%d%d%d",&n,&m,&l,&r);ans=0;
      for(i=1;i<=m;i++)p[i]=pow(i,n);
      for(i=2;i<=m;i++)for(a[i]=0,j=G[i/mul[i]];j;j=NXT[j])a[i]+=s[i][m/V[j]];
      while(l<=r)cal(l++);
      printf("%d\n",ans);
    }
  }
  return 0;
}

  

时间: 2025-01-13 01:28:56

BZOJ4635 : 数论小测验的相关文章

【C++探索之旅】第一部分第十三课:第一部分小测验

内容简介 1.第一部分十三课:第一部分小测验 2.第二部分第一课预告:面向对象初探,string的惊天内幕 第一部分小测验 上一课中,我们学习了指针这个重中之重. 那么,我们第一部分的课程也圆满地落幕了.不过,小编怎么会这么轻易放过你呢?(其实我是善良的社会主义好青年好嘛). 因此,必须来点简单的测试题,检测一下学习的果效.不难的,不要担心. 测试题目 1.C++之父是谁? Birj Tromman Bjarne Stroustrup Barj Grossoup 2.将文本编辑器,编译器和调试器

来试试这个来自静态代码分析工具PVS Studio提供C++的小测验吧

博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:来试试这个来自静态代码分析工具PVS Studio提供C++的小测验吧.

Java web 小测验

题目要求: 1登录账号:要求由6到12位字母.数字.下划线组成,只有字母可以开头:(1分) 2登录密码:要求显示“• ”或“*”表示输入位数,密码要求八位以上字母.数字组成.(1分) 3性别:要求用单选框或下拉框实现,选项只有“男”或“女”:(1分) 4学号:要求八位数字组成,前四位为“2018”开头,输入自己学号:(1分) 5姓名:输入自己的姓名: 5电子邮箱:要求判断正确格式[email protected]:(1分) 6点击“添加”按钮,将学生个人信息存储到数据库中.(3分) 7可以演示连

HTML 小测验记

HTML 测验 结果:11/9 1. HTML 指的是? 你的回答: 超链接和文本标记语言(Hyperlinks and Text Markup Language) 回答错误! 正确答案:超文本标记语言(Hyper Text Markup Language) 2. Web 标准的制定者是? 你的回答: 万维网联盟(W3C) 回答正确! 3. 在下列的 HTML 中,哪个是最大的标题? 你的回答: <h1> 回答正确! 4. 在下列的 HTML 中,哪个可以插入折行? 你的回答: <br&

数论小总结

质(素)数 : 任何数都能表示为质数的乘积,这应该是由质数的概念决定的,因为质数指:“质数(prime number)又称素数,有无限个.质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数.” ,所以合数肯定等于质数*某数,而某数又可以用这样的规则拆分成质数的乘积! 另外有这样一个定理,如果a,x与n互质,则a*x与n互质!!!   因为a,x,n拆分成质数后,a,x与n拆分出来的质数是不同的,并且质数*质数并不会产生另外的质数,所以res=a*x的质数组成和n的质数组成是完全不同的

noip考前抱佛脚 数论小总结

exCRT 求解韩信点兵问题,常见的就是合并不同\(mod\). 先mo一发高神的板子 for(R i=2;i<=n;++i){ ll Y1,Yi,lcm=Lcm(p[i],p[1]); exgcd(p[1],p[i],a[i]-a[1],Y1,Yi); add(a[1],mul(p[1],Y1,lcm),lcm),p[1]=lcm; } 思想是合并方程组,现在假设我们要求解的是: \[x-p_0*y_0=a_0\]\[x-p_i*y_i=a_i\] \(x\)是实际的值,显然有: \[p_0*

【RHELHAT】小测验一

考试信息: IPADDR: 172.25.x.100(X 在这里指您的工作站编号) NETMASK: 255.255.255.0 GATEWAY: 172.25.x.254 DNS: 172.25.254.254 yum源地址为:ftp://172.25.x.250/pub/rhel7.0 1. 在进行考试之前,请先重置根用户密码为 examwestos 2. 更改主机名称为 station.domainX.example.com(X 在这里指您的工作站编号) 3 新建组,名称为 sysadms

php,mysql 小测验 习题解析

判断题 判断题(共10题,每题2分)  1.php中布尔类型数据只有两个值:真和假.(    )ture 和flase的中文翻译逻辑型 2.php中连接两个字符串的符号是“+ ”.(   错   )  php中用的是‘.’不用‘.’ 3.php可以使用“scanf”来打印输出结果.(   错  ) scanf就不是用来打印结果的关键字 4.每个语句结尾都要加“:”来表示语句结束. ( 对     ) 固定格式 5.php变量使用之前需要定义变量类型.(   错  )因为php是一种弱类型语言所以

阿里的前端前期小测验

做完就感觉自己就是欠练...做题的时候着急.头脑一片白啥也想不起来了.只用了最简单的办法做还出了问题..比如什么审题啊.又或者连题意我都没读明白就开始做了,题很简单.但是错在我自己..把这道题粘出来以后做个教训吧... 实现一个方法genCssSelector,可以根据一个给定的元素生成一个CSS选择器,通过这个选择器可以快速定位到这个元素(document.querySelector(A))<!DOCTYPE html><html><head> <meta ch