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

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}^{ \lfloor m[1]/d \rfloor } \sum_{j=1}^{ \lfloor m[2]/d \rfloor } [(i, j)=1] (m[1]-id)(m[2]-jd) \binom{d-1}{c-2} \\
\end{align}
$$

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

$f(d)$表示范围内$i和j$的公约数只有最大公约数$d$时的对数,$F(d)$表示范围内$i和j$的公约数包括$d$的对数,那么由于最大公约数是所有公约数的约数,我们将有公约数$d$的所有最大公约数为$id$的都加起来就能得到$F(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( \lfloor \frac{m[1]}{i} \rfloor m[1] - i \frac{ \lfloor \frac{m[1]}{i} \rfloor ( \lfloor \frac{m[1]}{i} \rfloor + 1 ) }{2} \right) \left( \lfloor \frac{m[2]}{i} \rfloor m[2] - i \frac{ \lfloor \frac{m[2]}{i} \rfloor ( \lfloor \frac{m[2]}{i} \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( \lfloor \frac{m[j]}{i} \rfloor m[j] - i \frac{ \lfloor \frac{m[j]}{i} \rfloor ( \lfloor \frac{m[j]}{i} \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$,且仅当$ \lfloor \frac{m[j]}{i} \rfloor 不变时 $,有

$$
\sum_{j=0}^{n} a_ji^j =
\prod_{j=1}^{n} \left( \lfloor \frac{m[j]}{i} \rfloor m[j] - i \frac{ \lfloor \frac{m[j]}{i} \rfloor ( \lfloor \frac{m[j]}{i} \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(clnnm+Tn^3\sqrt{m})$

时间: 2024-07-31 14:29:03

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

BZOJ 3434 Wc2014 时空穿梭 莫比乌斯反演

题目大意:给定一个n维空间,需要在这n维空间内选取c个共线的点,要求这c个点每维坐标均单调递增,第i维坐标是整数且在[1,mi] 为了表述方便令||代表中间东西的方案数 顺便设第i维坐标为ai 但是这样不简洁因此用x表示第1维坐标,y表示第二维坐标,θ表示第n维坐标 貌似我的方法SB了?不管了总之自己能推出来真是太好了- - 尼玛BZOJ渣评测机卡常数- - 明明UOJ5s就全过了的说- - #include <cstdio> #include <cstring> #include

BZOJ3434 [Wc2014]时空穿梭

摔电脑摔电脑!JZP业界毒瘤! 400题纪念~哇终于上400了的说!!!好不容易欸! 题解什么的还是Orz iwtwiioi 我求组合数的方法明明是O(n)的,为什么这么慢!!!令人报警! 喂,话说这题的重点不在求组合数上面吧... 1 /************************************************************** 2 Problem: 3434 3 User: rausen 4 Language: C++ 5 Result: Accepted 6

BZOJ 3435: [Wc2014]紫荆花之恋

二次联通门 : BZOJ 3435: [Wc2014]紫荆花之恋 二次联通门 : luogu P3920 [WC2014]紫荆花之恋 /* luogu P3920 [WC2014]紫荆花之恋 怀疑人生 */ #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <ctime> #include <algorithm> #de

bzoj 3435: [Wc2014]紫荆花之恋 替罪羊树维护点分治 &amp;&amp; AC400

3435: [Wc2014]紫荆花之恋 Time Limit: 240 Sec  Memory Limit: 512 MBSubmit: 159  Solved: 40[Submit][Status][Discuss] Description 强 强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来. 仔细看看的话,这个大树实际上是一个带权树.每个时刻它会长出一个新的叶子节点.每个节点上有一个可爱的小精灵,

BZOJ 3435 Wc2014 紫荆花之恋 动态树分治+替罪羊树+Treap

题目大意:给定一棵树,每次添加一个节点并询问当前有多少点对满足dis(i,j)<=ri+rj 强制在线 吾辈有生之年终于把这道题切了...QAQ 什么?你想做这题? 1095切了么?没?去把1095切掉再说! 3065切了么?没?去把3065切掉再说! 什么?都切了?那还不会做这题?? -- 算了还是说说做法吧... 我们抛开那些乱七八糟的,考虑朴素做法 首先式子的形式是dis(i,j)<=ri+rj,令p=lca(i,j),把式子变形可以得到dis(j,p)-rj<=ri-dis(i,

To Do List

妈呀...发现不发博文公布自己要学的东西压力少太多了.......... 然后就会变得颓废..................... 求大家监督QAQ....To Do List是近3天左右目标,3天一更............. (而不是一大版一大版的............. =====================14.02.01-14.02.03:都快要WC了都...再不学点新东西就要滚粗了 可持久化trie:bzoj 2741 莫比乌斯反演(话说我原来写的都是点什么鬼....完全没用

东北育才10天大总结

老师们 Scanf的嗓门照例是最大的.恩. “我是山里的孩子……小的时候背书,整个山头都听得见……” 有一个哈师大附中的竞赛教练很……怎么说呢?接地气好了. Scanf说东北人很耿直,似乎确实是这样的.衡水的教练早就被遣返了…… “他啊,监考去了!” 虽然他不在,但还是不还手机.让衡水的人天天在电脑上颓废…… Scanf不在,你看我们就很老实.他到处“乱”玩,甚至跑到了国境线边,连火车票都忘了买,坐高铁去,乘绿皮火车回,路过长白山就去玩了一趟,结果暴风雪逼得他去吃“暴辣”的烤鱿鱼. “我看<三八

Oracle闪回技术详解

概述: 闪回技术是Oracle强大数据库备份恢复机制的一部分,在数据库发生逻辑错误的时候,闪回技术能提供快速且最小损失的恢复(多数闪回功能都能在数据库联机状态下完成).需要注意的是,闪回技术旨在快速恢复逻辑错误,对于物理损坏或是介质丢失的错误,闪回技术就回天乏术了,还是得借助于Oracle一些高级的备份恢复工具如RAMN去完成(这才是Oracle强大备份恢复机制的精髓所在啊)  撤销段(UNDO SEGMENT) 在讲闪回技术前,需要先了解Oracle中一个逻辑结构--撤销段.因为大部分闪回技术

【codevs 1911 孤岛营救问题】

·为了分析方便,可以先做一个题目简化.去掉"钥匙"这个条件,那么就是一个BFS或者SPFA--现在加上该条件.如本题只给出最多两种钥匙,当然你可以继续坚持BFS等方式,时间不会太差.但是一旦钥匙种类上升至15的时候,就有太多情况需要处理(光说你写BFS的if就是很长的过程,但个人认为时间复杂度依旧能过这道题). ·如图是简化版本的决策方式(为与后文呼应,用SPFA): 大方块是整个地图.小方块是一个房间.那么你可以在向四个方向走,前提是有路可走(没有墙).你本可以轻松拯救大兵瑞恩,然后