题目:http://uoj.ac/problem/54

想写20分。 Subtask 2 就是枚举4个维度的值的比例,可算对于一个比例有多少个值可以选,然后就是组合数。结果好像不对。

因为模数太小,组合数不能用阶乘的那个公式。不过 c*m 递推即可。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. using namespace std;
  5. int rdn()
  6. {
  7. int ret=;bool fx=;char ch=getchar();
  8. while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
  9. while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
  10. return fx?ret:-ret;
  11. }
  12. const int mod=;
  13. int Mn(int a,int b){return a<b?a:b;}
  14. int Mx(int a,int b){return a>b?a:b;}
  15. void upd(int &x){x>=mod?x-=mod:;}
  16. int pw(int x,int k)
  17. {int ret=;while(k){if(k&)ret=ret*x%mod;x=x*x%mod;k>>=;}return ret;}
  18. int gcd(int a,int b){return b?gcd(b,a%b):a;}
  19.  
  20. const int N=,M=1e5+,Q=;
  21. int T,n[Q],k[Q],m[Q][N],c[M][];
  22. void init_c(int n,int m)
  23. {
  24. for(int i=;i<=n;i++)c[i][]=;
  25. for(int i=;i<=n;i++)
  26. for(int j=,k=Mn(i,m);j<=k;j++)
  27. c[i][j]=c[i-][j]+c[i-][j-],upd(c[i][j]);
  28. }
  29. void solve1()
  30. {
  31. init_c(,);
  32. for(int t=;t<=T;t++) printf("%d\n",c[m[t][]][k[t]]);
  33. }
  34. int cs[],ans;
  35. void dfs(int cr,int bh)
  36. {
  37. if(cr>n[bh])
  38. {
  39. int mn=;
  40. for(int i=;i<=n[bh];i++)
  41. mn=Mn(mn,m[bh][i]/cs[i]);
  42. ans+=c[mn][n[bh]];upd(ans); return;
  43. }
  44. for(int i=,lm=m[bh][cr];i<=lm;i++)
  45. {
  46. bool flag=;
  47. for(int j=;j<cr;j++)
  48. if(gcd(cs[j],i)>){flag=;break;}
  49. if(flag)cs[cr]=i,dfs(cr+,bh);
  50. }
  51. }
  52. void solve3()
  53. {
  54. init_c(,);
  55. for(int t=;t<=T;t++)
  56. {
  57. ans=;dfs(,t);printf("%d\n",ans);
  58. }
  59. }
  60. int main()
  61. {
  62. T=rdn();bool fg1=,fg3=;
  63. for(int t=;t<=T;t++)
  64. {
  65. n[t]=rdn();k[t]=rdn();
  66. fg1|=(n[t]!=);
  67. for(int i=;i<=n[t];i++)m[t][i]=rdn(),fg3|=(m[t][i]>);
  68. }
  69. if(!fg1){solve1();return ;}
  70. if(!fg3){solve3();return ;}
  71. return ;
  72. }

正解是在枚举一组答案里的距离最远的两个点。可选的位置就是每一维的差值 xi 的 gcd +1 ,方案就是 \( C_{gcd-1}^{c-2} * \prod_{i=1}^{n}(m_{i}-x_{i}) \) ;然后反演一番之类的。

https://www.cnblogs.com/Zinn/p/10272661.html

当出现 \( \prod(m_{i}\left\lfloor\frac{m_{i}}{D}\right\rfloor - D\frac{(1+\left\lfloor\frac{m_{i}}{D}\right\rfloor)\left\lfloor\frac{m_{i}}{D}\right\rfloor}{2} \) 的时候,因为除了 D 以外的部分可以分块,所以把它看成关于 D 的多项式的想法很好。

虽然模数是 10007 ,两个乘起来也不会爆 int ,但 m[ i ] 很大,所以还是得到处写 (ll) 。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #define ll long long
  5. using namespace std;
  6. const int N=,C=,M=1e5+,mod=;
  7. int rdn()
  8. {
  9. int ret=;bool fx=;char ch=getchar();
  10. while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
  11. while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
  12. return fx?ret:-ret;
  13. }
  14. int Mx(int a,int b){return a>b?a:b;}
  15. int Mn(int a,int b){return a<b?a:b;}
  16. void upd(int &x){x>=mod?x-=mod:;x<?x+=mod:;}
  17. int pw(int x,int k){int ret=;while(k){if(k&)ret=ret*x%mod;x=x*x%mod;k>>=;}return ret;}
  18.  
  19. int T,c[M][C],u[M],f[N][C][M],pri[M],cnt;bool vis[M];
  20. void init()
  21. {
  22. int n=,nc=,m=1e5;
  23. u[]=;
  24. for(int i=;i<=m;i++)
  25. {
  26. if(!vis[i])pri[++cnt]=i,u[i]=-;
  27. for(int j=,d;j<=cnt&&(d=i*pri[j])<=m;j++)
  28. {
  29. vis[d]=;if(i%pri[j])u[d]=-u[i];else {u[d]=;break;}
  30. }
  31. }
  32. for(int i=;i<m;i++)c[i][]=;
  33. for(int k=nc-,i=;i<k;i++)
  34. for(int j=;j<=i;j++)c[i][j]=c[i-][j]+c[i-][j-],upd(c[i][j]);
  35. for(int k=nc-,i=k;i<m;i++)
  36. for(int j=;j<=k;j++)c[i][j]=c[i-][j]+c[i-][j-],upd(c[i][j]);
  37. for(int tc=;tc<=nc;tc++)
  38. {
  39. for(int i=;i<=m;i++)
  40. for(int j=i,k=;j<=m;j+=i,k++)
  41. f[][tc][j]+=c[i-][tc-]*u[k],upd(f[][tc][j]);
  42. for(int j=;j<=m;j++)
  43. for(int i=;i<=n;i++)f[i][tc][j]=f[i-][tc][j]*j%mod;
  44. }
  45. for(int i=;i<=n;i++)
  46. for(int tc=;tc<=nc;tc++)
  47. for(int j=;j<=m;j++)f[i][tc][j]+=f[i][tc][j-],upd(f[i][tc][j]);
  48. }
  49. int n,tc,a[N],m[N],tm[N];
  50. void cz(int bh)
  51. {
  52. memset(a,,sizeof a);a[]=;
  53. for(int i=;i<=n;i++)
  54. {
  55. int x=((ll)tm[i]*(tm[i]+)>>)%mod, y=(ll)tm[i]*m[i]%mod;//(ll)!!!
  56. x=-x; upd(x);//
  57. for(int j=n;j;j--)//--!!!
  58. a[j]=((ll)a[j-]*x+(ll)a[j]*y)%mod;
  59. a[]=a[]*y%mod;
  60. }
  61. }
  62. int cal()
  63. {
  64. int ret=;
  65. int lm=m[];for(int i=;i<=n;i++)lm=Mn(lm,m[i]);
  66. for(int i=,nt;i<=lm;i=nt+)
  67. {
  68. nt=lm;for(int j=;j<=n;j++)tm[j]=m[j]/i,nt=Mn(nt,m[j]/tm[j]);
  69. cz(i);
  70. for(int j=;j<=n;j++)ret=(ret+a[j]*(f[j][tc][nt]-f[j][tc][i-]))%mod,upd(ret);
  71. }
  72. return ret;
  73. }
  74. int main()
  75. {
  76. init();T=rdn();
  77. while(T--)
  78. {
  79. n=rdn();tc=rdn();for(int i=;i<=n;i++)m[i]=rdn();
  80. if(tc==)
  81. {
  82. int ret=;for(int i=;i<=n;i++)ret=ret*m[i]%mod;printf("%d\n",ret);
  83. }
  84. else printf("%d\n",cal());
  85. }
  86. return ;
  87. }

UOJ 54 【WC2014】时空穿梭——莫比乌斯反演的更多相关文章

  1. 【BZOJ3434】[Wc2014]时空穿梭 莫比乌斯反演

    [BZOJ3434][Wc2014]时空穿梭 Description Input 第一行包含一个正整数T,表示有T组数据求解每组数据包含两行,第一行包含两个正整数N,C(c>=2),分别表示空间 ...

  2. BZOJ 3434 [WC2014]时空穿梭 (莫比乌斯反演)

    题面:BZOJ传送门 洛谷传送门 好难啊..反演的终极题目 首先,本题的突破口在于直线的性质.不论是几维的空间,两点一定能确定一条直线 选取两个点作为最左下和最右上的点! 假设现在是二维空间,选取了$ ...

  3. [WC2014]时空穿梭(莫比乌斯反演)

    https://www.cnblogs.com/CQzhangyu/p/7891363.html 不难推到$\sum\limits_{D=1}^{m_1}\sum\limits_{d|D}C_{d-1 ...

  4. UOJ#54 BZOJ3434 [WC2014]时空穿梭

    题目描述 小 X 驾驶着他的飞船准备穿梭过一个 \(n\) 维空间,这个空间里每个点的坐标可以用 \(n\) 个实数表示,即 \((x_1,x_2,\dots,x_n)\). 为了穿过这个空间,小 X ...

  5. BZOJ3434 [Wc2014]时空穿梭

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  6. [WC2014]时空穿梭

    这才叫莫比乌斯反演题. 一.题目 点此看题 二.解法 也没有什么好的思路,我们不妨把暴力柿子写出来,我们想枚举直线,但是这道题不能枚举直线的斜率,所以就要用整数来表示直线,我们不妨枚举出发点和终止点的 ...

  7. BZOJ3434 WC2014时空穿梭(莫比乌斯反演)

    考虑枚举相邻点距离差的比例.显然应使比例值gcd为1以保证不重复统计.确定比例之后,各维坐标的方案数就可以分开考虑.设比例之和为k,则若坐标上限为m,该维坐标取值方案数即为Σm-ki (i=1~⌊m/ ...

  8. 【BZOJ】3434: [Wc2014]时空穿梭

    http://www.lydsy.com/JudgeOnline/problem.php?id=3434 题意:n维坐标中要找c个点使得c个点在一条线上且每一维的坐标单调递增且不能超过每一维限定的值m ...

  9. 莫比乌斯反演题表II

    bzoj3994:[SDOI2015]约数个数和 **很好推+有个小结论bzoj3309:DZY Loves Math ***很好推+线筛某函数/卡常bzoj4816:[Sdoi2017]数字表格 * ...

随机推荐

  1. mongodb的分片

    分片是把大型数据集合进行分区成更小的可管理的片的过程. 副本集的每一个成员(仲裁节点除外)都一份数据的完整拷贝! 分片的目的:在节省硬件成本的基础上,提高系统的整体性能.但是却增加了管理和性能的开销. ...

  2. 基于ORB的LinearBlend融合

    // L14//基于ORB实现线性融合#include "stdafx.h"#include <vector>#include <opencv2/core.hpp ...

  3. Linux内核分析04

    扒开系统调用的三层皮(上) 一,用户态.内核态和中断 用户态.内核态和中断的处理过程 用户态和内核态的区分 内核态:代码可以执行特权指令,访问任意的物理地址,CPU的这种执行级别就对应着~ 相对的用户 ...

  4. Java序列化(Serialization)

    关于Java的序列化的文章在网上已经够多了,在这里写关于Java序列化的文章是对自己关于这方面的的一种总结,结合以前的开发经验与网上的资料,写了这篇文章,对自己是有着巩固记忆的作用,也希望能够对大家有 ...

  5. ExtJS清除表格缓存

    背景 在使用ExtJS时遇到不少坑,如果不影响使用也无所谓,但是有些不能忍的,比如表格数据缓存问题.如果第一次打开页面查询出一些数据展示在表格中:第二次打开,即使不查询也会有数据,这是缓存的数据. 我 ...

  6. HDU 1438 钥匙计数之一(状压DP)题解

    思路: 每个槽有4种深度,一共有2^4种状态.然后开4维来保存每一次的状态:dp[ 第几个槽 ][ 当前状态 ][ 末尾深度 ][ 是否符合要求 ]. 代码: #include<cstdio&g ...

  7. supervisor安装与问题

    [转]安装supervisor以及可能碰到的问题 单击此处查看原文 supervisor作为一个进程管理的python软件非常的给力 但是一不小心就会遇到一些问题 就比如下面这个: unix:///v ...

  8. SDN原理 OpenFlow协议 -1

    本文基于SDN原理视频而成:SDN原理 OpenFlow OpenFlow 协议 和 传统的路由选择协议 有很多相似的地方,同时在某些地方也具有一定的颠覆性. 路由表,由IP地址和子网掩码组成.MAC ...

  9. 如何修改SQL Server 2008数据库服务器名称

    在做数据库发布订阅的时候我们经常要碰到要使用服务器名称来进行. 那么我们经常会碰到的问题是,现在开始大量的使用云服,我们只需要一台服务器搭建好环境,做一个备份镜像,还原到其他的服务器上就可以了,但是问 ...

  10. Rails 5 Test Prescriptions 第5章 Testing Models

    Rails,model层包含业务逻辑和储存逻辑.其中储存逻辑被ActiveRecord处理. 在model中,不是每件事都必须是ActiveRecord对象.model layer可以包含各种服务,对 ...