http://www.lydsy.com/JudgeOnline/problem.php?id=3434

题意:n维坐标中要找c个点使得c个点在一条线上且每一维的坐标单调递增且不能超过每一维限定的值m[i](n<=11, 2<=c<=20, m[i]<=100000)

#include <bits/stdc++.h>
using namespace std;
const int N=100005, MD=10007;
int C[N][19], g[21][N], f[21][12][N], a[12], p[N], pcnt, mu[N], MN;
bool np[N];
inline void check(int &x) { if(x>=MD || x<=-MD) x%=MD; }
void init() {
mu[1]=1;
for(int i=2; i<=MN; ++i) {
if(!np[i]) p[++pcnt]=i, mu[i]=-1;
for(int j=1; j<=pcnt; ++j) {
int t=i*p[j]; if(t>MN) break;
np[t]=1;
if(i%p[j]==0) { mu[t]=0; break; }
mu[t]=-mu[i];
}
}
C[0][0]=1;
for(int i=1; i<=MN; ++i) {
C[i][0]=1;
for(int j=1; j<19; ++j) C[i][j]=C[i-1][j-1]+C[i-1][j], check(C[i][j]);
}
for(int c=2; c<=20; ++c)
for(int i=1; i<=MN; ++i)
for(int j=i, k=1; j<=MN; j+=i, ++k)
g[c][j]+=C[i-1][c-2]*mu[k], check(g[c][j]);
for(int i=1; i<=MN; ++i)
for(int c=2; c<=20; ++c) {
int t=1;
for(int j=0; j<=11; ++j) {
f[c][j][i]=t*g[c][i]+f[c][j][i-1];
t*=i; check(t); check(f[c][j][i]);
}
}
}
int nn[1005], cc[1005], mm[1005][12], m[12], n, c;
typedef long long ll;
inline void cal(const int &xx) {
memset(a, 0, sizeof a);
a[0]=1;
static int b, bb, i, t, k;
for(k=0; k<n; ++k) {
t=m[k]/xx;
b=((ll)t*m[k])%MD; bb=-(((ll)t*(t+1))>>1)%MD;
for(i=n; i>=1; --i)
a[i]=(a[i]*b+a[i-1]*bb)%MD, check(a[i]);
a[0]*=b; check(a[0]);
}
}
int main() {
int T;
scanf("%d", &T);
for(int cs=1; cs<=T; ++cs) {
scanf("%d%d", &nn[cs], &cc[cs]);
for(int i=0; i<nn[cs]; ++i)
scanf("%d", &mm[cs][i]), MN=max(MN, mm[cs][i]);
}
init();
for(int cs=1; cs<=T; ++cs) {
n=nn[cs]; c=cc[cs];
int mx=~0u>>1, ans=0;
for(int i=0; i<n; ++i) m[i]=mm[cs][i], mx=min(mx, m[i]);
for(int i=1, pos=0; i<=mx; i=pos+1) {
pos=mx+1;
for(int d=0; d<n; ++d) pos=min(pos, m[d]/(m[d]/i));
cal(i);
for(int d=0; d<=n; ++d) ans+=a[d]*(f[c][d][pos]-f[c][d][i-1]), check(ans);
}
printf("%d\n", ((ans%MD)+MD)%MD);
}
return 0;
}

  

题解:

我真的不想写公式了= =QAQ

本题最神的两个地方,也就是我没有想到的地方:

1、问题的转化:我们只需要在这些多维空间中确定两个端点,那么所有的点一定在这两个端点的线段上边就是了,而且不会重合。那么我们可以枚举两个端点的坐标差$i和j$(为了方便我们先设二维的,然后再推广),由于线端上整点的的数目就是$gcd(i, j)-1$(不包含端点),所以我们可以立即得到公式(待会写)。

2、公式的处理。由于推出公式后,会发现有一部分不能分块QAQ,因为是枚举$gcd$,而式子里边存在着乘法.....因此稍加处理(下边写)..

那么本题如果没有以上两点就是纯水题了.....

一下均设$m[i]<=m[j], i<=j$,因为这是没有影响的,下标是二维的情形

容易得到公式:

$$
\begin{align}
ans
= & \sum_{i=1}^{m[1]} \sum_{j=1}^{m[2]} (m[1]-i)(m[2]-j) \binom{(i, j)-1}{c-2} \\
= & \sum_{d=1}^{m[1]} \sum_{i=1}^{ \left \lfloor m[1]/d \right \rfloor } \sum_{j=1}^{ \left \lfloor m[2]/d \right \rfloor } [(i, j)=1] (m[1]-id)(m[2]-jd) \binom{d-1}{c-2} \\
\end{align}
$$

$$ f(d) = \sum_{i=1}^{ \left \lfloor m[1]/d \right \rfloor } \sum_{j=1}^{ \left \lfloor m[2]/d \right \rfloor }
[(i, j)=1] (m[1]-id)(m[2]-jd) $$
$$ F(d) = \sum_{i=1}^{ \left \lfloor m[1]/d \right \rfloor } \sum_{j=1}^{ \left \lfloor m[2]/d \right \rfloor }
(m[1]-id)(m[2]-jd) $$

$F(d)$计算的是$(i, j)=kd$时情况,$f(d)$计算的是$(i, j)=d$时的情况,所以

$$ F(d) = \sum_{d|n} f(n) $$

那么就能反演啦...即

$$ f(d) = \sum_{d|n} \mu ( \frac{n}{d} ) F(n) $$

最后推得:

$$
ans = \sum_{i=1}^{m[1]} \left( \left \lfloor \frac{m[1]}{i} \right \rfloor m[1] - i \frac{ \left \lfloor \frac{m[1]}{i} \right \rfloor ( \left \lfloor \frac{m[1]}{i} \right \rfloor + 1 ) }{2} \right) \left( \left \lfloor \frac{m[2]}{i} \right \rfloor m[2] - i \frac{ \left \lfloor \frac{m[2]}{i} \right \rfloor ( \left \lfloor \frac{m[2]}{i} \right \rfloor + 1 ) }{2} \right) \sum_{d|i} \mu ( \frac{i}{d} ) \binom{i-1}{c-2}
$$

发现后边和$m$是无关的= =,因此拓展就是将前边的东西合起来= =,即

$$
ans = \sum_{i=1}^{m[1]} \prod_{j=1}^{n} \left( \left \lfloor \frac{m[j]}{i} \right \rfloor m[j] - i \frac{ \left \lfloor \frac{m[j]}{i} \right \rfloor ( \left \lfloor \frac{m[j]}{i} \right \rfloor + 1 ) }{2} \right) \sum_{d|i} \mu ( \frac{i}{d} ) \binom{i-1}{c-2}
$$

$$ g(i) = \sum_{d|i} \mu ( \frac{i}{d} ) \binom{i-1}{c-2} $$

然后$O(nlnn)$的暴力求出$g(i)$你总会的吧= =

但是现在关键是答案里面有个$i$的乘法因子 QAQ否则就能直接出解了..

可是发现这样乘起来是关于$i$的多项式...那么设系数向量$a$,且仅当$ \left \lfloor \frac{m[j]}{i} \right \rfloor 不变时 $,有

$$
\sum_{j=0}^{n} a_ji^j =
\prod_{j=1}^{n} \left( \left \lfloor \frac{m[j]}{i} \right \rfloor m[j] - i \frac{ \left \lfloor \frac{m[j]}{i} \right \rfloor ( \left \lfloor \frac{m[j]}{i} \right \rfloor + 1 ) }{2} \right)
$$

最后原式变为

$$
\begin{align}
ans_x
= & \sum_{i=1}^{m[1]} \sum_{j=0}^{n} a_ji^j g(i) \\
= & \sum_{j=0}^{n} a_j \sum_{i=1}^{m[1]} i^j g(i) \\
\end{align}
$$

然后暴力预处理你怕不怕= =

时间复杂度为:$O(cmlog(n)+Tn^3\sqrt{m})$

【BZOJ】3434: [Wc2014]时空穿梭的更多相关文章

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

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

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

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

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

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

  4. BZOJ3434 [Wc2014]时空穿梭

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

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

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

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

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

  7. [WC2014]时空穿梭

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

  8. BZOJ 3435: [Wc2014]紫荆花之恋

    二次联通门 : BZOJ 3435: [Wc2014]紫荆花之恋 二次联通门 : luogu P3920 [WC2014]紫荆花之恋 /* luogu P3920 [WC2014]紫荆花之恋 怀疑人生 ...

  9. Vue2 实现时空穿梭框功能模块

    前言 这篇文章主要是分享一个时空穿梭框功能,也就是我们平时用的选择功能.勾选了的项就会进入到另一个框中. 时空穿梭框之旅 示例演示: 这个时空穿梭框实现了: 1.可以全选.反选 2.没有选中时,不可以 ...

随机推荐

  1. 常用的数据统计Sql 总结(转)

    转:http://www.cnblogs.com/zhangweizhong/p/5577842.html 最近刚在搞一个BI的项目,里面需要大量的sql 数据统计相关运用,加深了我又对SQL的理解与 ...

  2. Chrome Crx 插件下载

    扯蛋的GFW屏蔽了google域导致下载Chrome插件加载失败,本人想收集以些chrome的Crx插件,可供直接下载 XMarks - 在不同电脑不同浏览器之间同步书签 下载地址:   http:/ ...

  3. SQL Server 2014 BI新特性(三)Power Query和Power Map功能预览

    Power Query和Power Map是微软前不久在WPC上发布的Power BI中新的针对Excel的功能.借助这两样功能,自助式BI将更方便你发现和处理数据并且丰富数据的可视化功能. Powe ...

  4. Android 线程更新UI报错 : Can't create handler inside thread that has not called Looper.prepare()

    MainActivity中有一个按钮,绑定了save方法 public void save(View view) { String title = titleText.getText().toStri ...

  5. android 入门-android Studio 快捷输入

    1.输入 log的时候按一下Tab.就会打出 private static final String TAG="Settings"; 2. shift +alt+x 运行 shif ...

  6. java中的负数的问题

    在计算机中是使用二制数中的最高位表示来正负. 二进制的储存中都是用的补码,正数的原码.反码和补码相同,负数的原码是最高位为1,反码最高位不变,其余各位取反,补码为其反码+1(重要!!) 首先得知道最高 ...

  7. LayoutInflater(二)

    每一个视图的绘制过程都必须经历三个最主要的阶段,即onMeasure().onLayout()和onDraw(),下面我们逐个对这三个阶段展开进行探讨. 一. onMeasure() measure是 ...

  8. C语言常用知识

    跳出for循环主要有以下2中方式: 1.用break语句.如: int i; for(i=0; i<10; i++) {     if(i>3)    // 如果i>3,跳出for循 ...

  9. ViewPager+tab+Fragment的滑动

    package teamhgl.xinwensudu; import android.os.Bundle;import android.support.v4.app.Fragment;import a ...

  10. python 多重继承

    多重继承 除了从一个父类继承外,Python允许从多个父类继承,称为多重继承. 多重继承的继承链就不是一棵树了,它像这样: class A(object): def __init__(self, a) ...