BZOJ 4807 車 组合数学
思路:高精度\((what)\)
提交:2次(后来发现有种更快的写法)
题解:
设\(n>m\),那么显然答案为\(C(n,m)\),相当于只能放\(m\)个棋子,可以在\(n\)列中选任意不同的\(m\)列上。
刚开始是这种解法:(\(3560ms\))
#include<cstdio>
#include<iostream>
#define ull unsigned long long
#define ll long long
#define R register int
using namespace std;
#define pause (for(R i=1;i<=10000000000;++i))
#define In freopen("NOIPAK++.in","r",stdin)
#define Out freopen("out.out","w",stdout)
namespace Fread {
static char B[1<<15],*S=B,*D=B;
#ifndef JACK
#define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++)
#endif
inline int g() {
R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
if(ch==EOF) return EOF; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
} inline bool isempty(const char& ch) {return (ch<=36||ch>=127);}
inline void gs(char* s) {
register char ch; while(isempty(ch=getchar()));
do *s++=ch; while(!isempty(ch=getchar()));
}
} using Fread::g; using Fread::gs;
namespace Luitaryi {
const int N=1000010;
const ll B=1E+10;
int n,m,sz=1,c[N];
ll a[7];
inline void inc(int x) {for(R i=2;i*i<=x;++i) while(x%i==0) x/=i,++c[i]; if(x&&x!=1) ++c[x];}
inline void dec(int x) {for(R i=2;i*i<=x;++i) while(x%i==0) x/=i,--c[i]; if(x&&x!=1) --c[x];}
inline void mul(int x) { register ll tmp=0;
for(R i=1;i<=sz;++i) {
a[i]*=x,a[i]+=tmp;
tmp=a[i]/B,a[i]%=B;
} if(tmp) ++sz,a[sz]=tmp; if(sz>5) sz=5;
}
inline void calc() {for(R i=2;i<=n;++i) while(c[i]) mul(i),--c[i];}
inline void main() {
n=g(),m=g(); m>n?swap(n,m):void(0);
if(m==n) return (void)printf("1\n");
for(R i=n;i>m;--i) inc(i);
for(R i=2;i<=n-m;++i) dec(i);
a[1]=1; calc(); printf("%lld",a[sz]); for(R i=sz-1;i;--i) printf("%010lld",a[i]);
}
}
signed main() {
Luitaryi::main(); return 0;
}
后来看到有这样的:(快的一批\(260ms\))
#include<cstdio>
#include<iostream>
#define ull unsigned long long
#define ll long long
#define R register int
using namespace std;
#define pause (for(R i=1;i<=10000000000;++i))
#define In freopen("NOIPAK++.in","r",stdin)
#define Out freopen("out.out","w",stdout)
namespace Fread {
static char B[1<<15],*S=B,*D=B;
#ifndef JACK
#define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++)
#endif
inline int g() {
R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
if(ch==EOF) return EOF; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
}
} using Fread::g;
namespace Luitaryi {
const int N=1000010;
const ll B=1E+10;
int n,m,sz=1,cnt,c[N],mnd[N],pri[N>>1];
ll a[7];
inline void PRE(int n) {
for(R i=2;i<=n;++i) {
if(!mnd[i]) mnd[i]=i,pri[++cnt]=i;
for(R j=1;j<=cnt&&i*pri[j]<=n;++j) {
mnd[i*pri[j]]=pri[j];
if(i%pri[j]==0) break;
}
}
}
inline void inc(int x) {while(x>1) ++c[mnd[x]],x/=mnd[x];}
inline void dec(int x) {while(x>1) --c[mnd[x]],x/=mnd[x];}
inline void mul(int x) { register ll tmp=0;
for(R i=1;i<=sz;++i) {
a[i]*=x,a[i]+=tmp;
a[i]>=B?tmp=a[i]/B,a[i]%=B:tmp=0;
} if(tmp) a[++sz]=tmp; if(sz>5) sz=5;
}
inline void calc() {for(R i=1;i<=cnt;++i) while(c[pri[i]]) mul(pri[i]),--c[pri[i]];}
inline void main() {
n=g(),m=g(); m>n?swap(n,m):void(0); PRE(n);
if(m==n) return (void)printf("1\n");
for(R i=n;i>m;--i) inc(i);
for(R i=2;i<=n-m;++i) dec(i);
a[1]=1; calc(); printf("%lld",a[sz]); for(R i=sz-1;i;--i) printf("%010lld",a[i]);
}
}
signed main() {
Luitaryi::main(); return 0;
}
\(zz\)忽然感受到我数学白学了
2019.07.23
BZOJ 4807 車 组合数学的更多相关文章
- bzoj 4807: 車【组合数+高精+线性筛】
设n>m,答案是\( C_n^m \),然后高精就行了 具体做法是先把指数筛出来,然后对每个数因数分解,记录质因子个数,最后被除数减去除数质因子个数,把剩下的质因子乘起来就行了 #include ...
- BZOJ4807:車(组合数学,高精度)
Description 众所周知,車是中国象棋中最厉害的一子之一,它能吃到同一行或同一列中的其他棋子.車跟車显然不能在一起打起来,于是rly一天又借来了许多许多的車在棋盘上摆了起来……他想知道,在N× ...
- BZOJ 3997: [TJOI2015]组合数学 [偏序关系 DP]
3997: [TJOI2015]组合数学 题意:\(n*m:\ n \le 1000\)网格图,每个格子有权值.每次从左上角出发,只能向下或右走.经过一个格子权值-1.至少从左上角出发几次所有权值为0 ...
- bzoj 3907: 网格 组合数学
3907: 网格 Time Limit: 1 Sec Memory Limit: 256 MBSubmit: 13 Solved: 7[Submit][Status][Discuss] Descr ...
- bzoj 3997 [TJOI2015]组合数学(DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3997 [题意] 给定一个nm的长方形,每次只能使经过格子权值减1,每次只能向右向下,问 ...
- BZOJ 3997 TJOI2015 组合数学
分析一下样例就可以知道,求的实际上是从左下角到右上角的最长路 因为对于任意不在这个最长路的上的点,都可以通过经过最长路上的点的路径将这个点的价值减光 (可以用反证法证明) 之后就是一个非常NOIP的D ...
- BZOJ 1008 越狱 (组合数学)
题解:正难则反,从总数中减去全部相邻不相同的数目就是答案,n*(n-1)^(m-1):第一个房间有n中染色方案,剩下m-1个房间均只有n-1种染色方案,用总数减就是答案. #include <c ...
- BZOJ 2142 礼物 组合数学 CRT 中国剩余定理
2142: 礼物 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 1450 Solved: 593[Submit][Status][Discuss] ...
- BZOJ 1008 越狱 组合数学
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1008 题目大意: 监狱有连续编号为1...N的N个房间,每个房间关押一个犯人,有M种宗 ...
随机推荐
- vector简单常用用法
Vector是什么? vector翻译为向量,从某种角度来说就是一个可以变长的数组,它会根据需要自动扩充数组的容量,除此之外其是一个STL中的模板类,其 还具有一些内部的方法. Vector的使用方法 ...
- SAS学习笔记32 select语句
- JS 05 json
1.下载jar包: https://www.github.com/alibaba/fastjson/releases https://www.mvnrepository.com/artifact/co ...
- 基于Task的多线程
/// <summary> /// 基于Task的多线程 /// </summary> public class Tasks { public static void Task ...
- MongoDB操作-备份和恢复
Mongodb数据库操作-备份 恢复 导出 导入 mongodb数据备份和恢复主要分为二种:一种是针对库的mongodump和mongorestore,一种是针对库中表的mongoexport和mon ...
- aliplay获取播放时长
<div id="player-con" class="frequency-pic"></div> <link rel=" ...
- 根据xsd文件生成对应的C#类,然后创建对应的xml文件
首先用xsd文件生产对应的C#类,这个VS已经自带此工单,方法如下: 1. 打开交叉命令行工具 2. 输入如下指令 xsd d:\123.xsd /c /language:C# /outputdir: ...
- centos mysql数据库问题:ERROR 1044 (42000): Access denied for user ''@'localhost' to database 'mysql'(转)
问题描述: 安装好数据库MySQL,进入mysql,设置号密码后,退出的时候,利用密码无法进入,直接回车后可进入,无法看到数据库mysql,use mysql返回错误:ERROR 1044 (4200 ...
- kong命令(四)upstream
介绍 upstream 就是一个虚拟的服务.可用于配置多个target目标服务时实现负载均衡的效果. 注意:service的host指的就是upstream的name. 同时upstream提供了一个 ...
- 在SAP云平台ABAP编程环境上编写第一段ABAP程序
距2017年秋季的SAP TechEd大会上一位大佬Björn Goerke,SAP's Chief Technology Officer宣布了SAP Cloud Platform即将支持ABAP至今 ...