题解 b
考场上只会暴力 \(n^4\) DP,部分分还写炸了
但其实这个DP可以前缀和优化到 \(n^3\) ,我觉得没有这档部分分就没写
但其实是有这一档的,我没有看出来……
正解想不到
如果我们已知使选的所有数 \(i\) 都满足 \(i \mid gcd\) 的方案数,就可以容斥得到答案
所以先求有多少种选择方案使得选的所有数均为 \(i\) 的倍数的方案数
然后考虑这一步如何容斥
发现对于 \(i > \lfloor \frac{n}{2} \rfloor\) 上面求出来的结果就是答案,因为没有倍数可以让它算重
然后对于这个分界线左边的第一个数,我们可以减掉它的倍数的方案数(这些方案数一定是正确的)来得到它的正确方案数
于是这个分界线左移了一位
重复上述过程,就可以得到答案了
Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define ll long long
#define reg register int
//#define int long long
char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
int ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
}
int n, m;
int a[25][N], maxn, sta[N<<2], top, vis2[25][N];
bool vis[N];
ll dp[25][N], ans;
const ll p=1e9+7;
int gcd(int a, int b) {return !b?a:gcd(b, a%b);}
namespace task1{
void solve() {
for (reg i=1; i<=n; ++i)
for (reg j=1; j<=m; ++j)
sta[++top]=a[i][j];
sort(sta+1, sta+top+1);
top=unique(sta+1, sta+top+1)-sta-1;
for (reg i=1; i<=top; ++i) {
vis[sta[i]]=1;
for (reg j=1; j<=top; ++j)
vis[gcd(sta[i], sta[j])]=1;
}
for (reg i=n; i; --i) {
for (reg j=1; j<=maxn; ++j) if (vis[j]) {
dp[i][j]=j;
for (reg k=i+1; k<=n; ++k) {
for (reg h=1; h<=m; ++h) {
dp[i][j] = (dp[i][j]+dp[k][gcd(j, a[k][h])])%p;
}
}
}
}
for (reg i=1; i<=n; ++i)
for (reg j=1; j<=m; ++j)
ans = (ans+dp[i][a[i][j]])%p;
printf("%lld\n", ans);
exit(0);
}
}
namespace task2{
void solve() {
ll ans=0;
for (int i=1; i<=m; ++i) ans=(ans+a[1][i])%p;
printf("%lld\n", ans);
exit(0);
}
}
namespace task3{
ll fac[N], inv[N], mic[N], ans;
ll C(int n, int k) {if (n==k) return 1ll; return !k?1ll:fac[n]*inv[k]%p*inv[n-k]%p;}
void solve() {
fac[0]=fac[1]=1; inv[0]=inv[1]=1; mic[0]=1;
for (int i=2; i<=n; ++i) fac[i]=fac[i-1]*i%p;
for (int i=2; i<=n; ++i) inv[i]=(p-p/i)*inv[p%i]%p;
for (int i=2; i<=n; ++i) inv[i]=inv[i-1]*inv[i]%p;
for (int i=1; i<=n+1; ++i) mic[i]=mic[i-1]*m%p;
for (int i=1; i<=n; ++i)
for (int j=0; j<=n-i; ++j)
ans = (ans+C(n-i, j)*mic[j+1]%p)%p;
printf("%lld\n", ans*a[1][1]%p);
exit(0);
}
}
namespace task{
ll cnt[25][N], met[N], ans;
void solve() {
for (int i=1; i<=n; ++i) {
cnt[i][1]=m;
for (int j=2; j<=maxn; ++j)
for (int k=1; k*j<=maxn; ++k)
cnt[i][j]+=vis2[i][k*j];
}
//cout<<"cnt: "; for (int i=1; i<=maxn; ++i) cout<<cnt[1][i]<<' '; cout<<endl;
for (int i=1; i<=maxn; ++i) {
met[i]=1;
for (int j=1; j<=n; ++j)
met[i]=met[i]*(cnt[j][i]+1)%p;
--met[i];
}
//cout<<"met: "; for (int i=1; i<=maxn; ++i) cout<<met[i]<<' '; cout<<endl;
for (int i=maxn; i; --i) {
for (int j=2; i*j<=maxn; ++j) met[i]-=met[i*j];
ans = (ans+met[i]*i)%p;
}
//cout<<"met: "; for (int i=1; i<=maxn; ++i) cout<<met[i]<<' '; cout<<endl;
printf("%lld\n", ((ans%p)+p)%p);
exit(0);
}
}
signed main()
{
bool same=1; int lst=0;
n=read(); m=read();
for (reg i=1; i<=n; ++i)
for (reg j=1; j<=m; ++j) {
a[i][j]=read();
maxn=max(maxn, a[i][j]);
++vis2[i][a[i][j]];
if (!lst) lst=a[i][j];
else if (lst!=a[i][j]) same=0;
}
//if (n==1) task2::solve();
//else if (same) task3::solve();
//else task1::solve();
task::solve();
return 0;
}
题解 b的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
- JSOI2016R3 瞎BB题解
题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...
随机推荐
- Window server 2016 搭建Java Web环境
系统下载 下载种子(迅雷下载): ed2k://|file|cn_windows_server_2016_updated_feb_2018_x64_dvd_11636703.iso|629426585 ...
- FirstDay
昨天心血来潮,想着注册一博客,没想到今天再登时,审阅就通过了,多少有点庆辛.从今天起,我也算是有博客的人了! 为什么选博客园开通?好多IT论坛里都允许有博文,CSDN感觉过于高大上,其他系列论坛大多内 ...
- 使用Nginx将请求转发至Google Analytics实现后端数据统计
前言 Google Analytics 加载缓慢是本博客在国内访问缓慢的原因之一.虽然通过使用大公司的 ga.js 的 CDN ,可以很大程度上加快加载 ga.js 文件的速度( ga.js 的更新频 ...
- SpringBoot缓存管理(三) 自定义Redis缓存序列化机制
前言 在上一篇文章中,我们完成了SpringBoot整合Redis进行数据缓存管理的工作,但缓存管理的实体类数据使用的是JDK序列化方式(如下图所示),不便于使用可视化管理工具进行查看和管理. 接下来 ...
- C语言:编程求任意月份的天数
闰年问题,因为二月份的天数与闰年有关.闰年的判断依据是:若某年能被4整除,但不能被100整除,则这一年是闰年:若某年能被400整除,则这一年也是闰年 #include <stdio.h> ...
- 【Java数据结构与算法】简单排序、二分查找和异或运算
简单排序 选择排序 概念 首先,找到数组中最小的那个元素,其次,把它和数组的第一个元素交换位置(如果第一个元素就是最小的元素那么它就和自己交换).再次,在剩下的元素中找到最小的元素,将它与数组的第二个 ...
- [004] - JavaSE面试题(四):JavaSE语法(2)
第一期:Java面试 - 100题,梳理各大网站优秀面试题.大家可以跟着我一起来刷刷Java理论知识 [004] - JavaSE面试题(四):JavaSE语法(2) 第1问:重载(overload) ...
- js浮点数保留位数方法封装
大家在平时业务中应该经常跟小数打交道吧,有没有被小数点的保留位数问题搞得头疼啊.比如,保留一位小数,保留俩位小数,保留三位小数,向上取整.四舍五入等等. 而我最近在项目中正好遇到类似的问题:有的地方要 ...
- Luogu2839 [国家集训队]middle 题解
题目很好,考察对主席树的深入理解与灵活运用. 首先看看一般解决中位数的思路,我们二分一个 \(mid\),将区间中 \(\ge mid\) 的数置为 \(1\),小于的置为 \(-1\),然后求区间和 ...
- 认识微信小程序开发页面
先认识一下开发界面,当前是上节中刚刚新建好的一个小程序. 模拟窗口当前页面的路径可以查看左下角Page Path,可以看到当前页面的路径为pages/index/index,正好和app.json里面 ...