朝鲜时蔬
- decription
- solution
- code
decription
对于一个有穷非空正整数集合S={x1,x2,x3,...,xn}⊂N+(n≥1)S=\{x_1,x_2,x_3,...,x_n\}\subset N^+(n\ge 1)S={x1,x2,x3,...,xn}⊂N+(n≥1),定义其和sum(S)sum(S)sum(S)为所有元素的和
- sum(S)=x1+...+xnsum(S)=x_1+...+x_nsum(S)=x1+...+xn
定义其m(1≤m≤n)m(1\le m\le n)m(1≤m≤n)阶子集集合Sm(S)\mathfrak{S}_m(S)Sm(S)为其所有mmm阶子集的集合
- Sm(S)={T∣T={y1,…,ym}⊆S}\mathfrak{S}_m(S)=\Big\{T\Big|T=\{y_1,\dots,y_m\}\subseteq S\Big\}Sm(S)={T∣∣∣T={y1,…,ym}⊆S}
TTT就是从SSS中选mmm个不同数的组成的一个子集,Sm(S)\mathfrak{S}_m(S)Sm(S)就是子集TTT所有情况的集合
定义其k(1≤k≤n)k(1\le k\le n)k(1≤k≤n)级价值子集集Tk(S)\mathfrak{T}_k(S)Tk(S)为其所有kkk阶子集中和整除sum(S)sum(S)sum(S)的
- Tk(S)={T∣k=sum(S)sum(T)∧k∈N+}⋂Sk(S)\mathfrak{T}_k(S)=\Big\{T\Big|k=\frac{sum(S)}{sum(T)}\wedge k\in N^+\Big\}\bigcap\mathfrak{S}_k(S)Tk(S)={T∣∣∣k=sum(T)sum(S)∧k∈N+}⋂Sk(S)
就是满足上一个要求的基础上,子集元素和能整除原来的大集合的子集的集合
定义其m(1≤m≤n)m(1\le m\le n)m(1≤m≤n)阶k(1≤k≤m)k(1\le k\le m)k(1≤k≤m)级价值函数为其所有mmm阶子集中kkk级价值子集集的阶的最大值
- fm,k(S)=max{∣Tk(T)∣∣T∈Sm(S)}f_{m,k}(S)=\max\Big\{|\mathfrak{T}_{k}(T)|\quad\Big|\quad T\in\mathfrak{S}_m(S)\Big\}fm,k(S)=max{∣Tk(T)∣∣∣∣T∈Sm(S)}
定义其m(1≤m≤n)m(1\le m\le n)m(1≤m≤n)阶k(1≤k≤m)k(1\le k\le m)k(1≤k≤m)级价值函数的值点集合Pm,k(S)\mathfrak{P}_{m,k}(S)Pm,k(S)为取到上述最大值的mmm阶子集的集合
- Pm,k(S)={T∣∣Tk(T)∣=fm,k(S)}⋂Sm(S)\mathfrak{P}_{m,k}(S)=\Big\{T\quad\Big|\quad |\mathfrak{T}_k(T)|=f_{m,k}(S)\Big\}\bigcap\mathfrak{S}_m(S)Pm,k(S)={T∣∣∣∣Tk(T)∣=fm,k(S)}⋂Sm(S)
给出n,m,kn,m,kn,m,k,表示集合S=1,2,...,nS={1,2,...,n}S=1,2,...,n
求∣Pm,k(S)∣|\mathfrak{P}_{m,k}(S)|∣Pm,k(S)∣,即有多少个mmm阶子集能取到最大值,答案对109+710^9+7109+7取模
1≤n≤10121\le n\le 10^{12}1≤n≤1012
子任务编号 | 分值 | m= | k= |
---|---|---|---|
1 | 10 | 1 | 1 |
2 | 10 | 2 | 1 |
3 | 10 | 2 | 2 |
4 | 10 | 3 | 1 |
5 | 10 | 3 | 2 |
6 | 10 | 3 | 3 |
7 | 10 | 4 | 1 |
8 | 10 | 4 | 2 |
9 | 10 | 4 | 3 |
10 | 10 | 4 | 4 |
solution
这种分数据点写不同算法的题真的很不错,如果不那么绕弯子就更好了!
有些点直接写吐了,giao
实际上,上面的四种定义,从后往前看其实很像递归的感觉,而我们就需要在这种递归思想中找到答案的规律!(证明也行)
倒着看,实际上是最开始的集合S={1,2,...,n}S=\{1,2,...,n\}S={1,2,...,n},从中选mmm个定义为子集T={x1,...,xm}T=\{x_1,...,x_m\}T={x1,...,xm},再从TTT中选kkk个定义为子子集PPP
m=k
显然只要从SSS中选出mmm个后,TTT中选kkk个组成的PPP,一定满足sum(T)=sum(P)sum(T)=sum(P)sum(T)=sum(P)
所以答案就是从nnn个中选mmm个的方案数
C(n,m)C(n,m)C(n,m)
void subtask1() {int ans = 1;for( int i = n;i > n - m;i -- )ans = i % mod * ans % mod;for( int i = 1;i <= m;i ++ )ans = ans * qkpow( i, mod - 2 ) % mod;printf( "%lld\n", ans );
}
m=2,k=1
不妨假设正整数x1<x2x_1<x_2x1<x2
由于x2∤x1⇒x2∤(x1+x2)x_2\nmid x_1\Rightarrow x_2\nmid(x_1+x_2)x2∤x1⇒x2∤(x1+x2),(显然较大值不会是较小值的因数,不可能整除)
所以只可能有x1∣x2⇒x1∣(x1+x2)x_1\mid x_2\Rightarrow x_1\mid(x_1+x_2)x1∣x2⇒x1∣(x1+x2)
枚举x1=ix_1=ix1=i,则x2=k∗i,k∈[2,⌊ni⌋]x_2=k*i,k\in[2,\lfloor\frac{n}{i}\rfloor]x2=k∗i,k∈[2,⌊in⌋],即有⌊ni⌋−2+1=⌊ni⌋−1\lfloor\frac{n}{i}\rfloor-2+1=\lfloor\frac{n}{i}\rfloor-1⌊in⌋−2+1=⌊in⌋−1
答案为∑i=1n(⌊ni⌋−1)\sum_{i=1}^n(\lfloor\frac{n}{i}\rfloor-1)i=1∑n(⌊in⌋−1)
按照⌊ni⌋\lfloor\frac{n}{i}\rfloor⌊in⌋分块,连续一段区间[l,r][l,r][l,r]的⌊ni⌋\lfloor\frac{n}{i}\rfloor⌊in⌋相同
void subtask2() {int ans = 0;for( int r = n, l;r > 0;r = l - 1 ) {if( r == 1 ) break;l = n / ( n / r + 1 ) + 1;int t = n / r;ans = ( ans + t % mod * ( r - l + 1 ) % mod ) % mod;}printf( "%lld\n", ans );
}
m=3,k=1
假设nnn足够大且存在x1<x2<x3x_1<x_2<x_3x1<x2<x3满足
{x1∣(x1+x2+x3)x2∣(x1+x2+x3)x3∣(x1+x2+x3)\begin{cases} x_1\mid (x_1+x_2+x_3)\\ x_2\mid (x_1+x_2+x_3)\\ x_3\mid (x_1+x_2+x_3) \end{cases} ⎩⎪⎨⎪⎧x1∣(x1+x2+x3)x2∣(x1+x2+x3)x3∣(x1+x2+x3)
不失一般性假设正整数1<x<y<z1<x<y<z1<x<y<z,即1>1x>1y>1z1>\frac{1}{x}>\frac{1}{y}>\frac{1}{z}1>x1>y1>z1
满足
{z∗x1=x1+x2+x3y∗x2=x1+x2+x3x∗x3=x1+x2+x3⇒{x1x1+x2+x3=1zx2x1+x2+x3=1yx3x1+x2+x3=1x\begin{cases} z*x_1 = x_1+x_2+x_3\\ y*x_2 = x_1+x_2+x_3\\ x*x_3 = x_1+x_2+x_3 \end{cases}\\ \Rightarrow \begin{cases} \frac{x_1}{x_1+x_2+x_3}=\frac{1}{z}\\ \frac{x_2}{x_1+x_2+x_3}=\frac{1}{y}\\ \frac{x_3}{x_1+x_2+x_3}=\frac{1}{x}\\ \end{cases} ⎩⎪⎨⎪⎧z∗x1=x1+x2+x3y∗x2=x1+x2+x3x∗x3=x1+x2+x3⇒⎩⎪⎨⎪⎧x1+x2+x3x1=z1x1+x2+x3x2=y1x1+x2+x3x3=x1
则有1x+1y+1z=1\frac{1}{x}+\frac{1}{y}+\frac{1}{z}=1x1+y1+z1=1,且1=1x+1y+1z<3x⇒x<3⇒x=21=\frac{1}{x}+\frac{1}{y}+\frac{1}{z}<\frac{3}{x}\Rightarrow x<3\Rightarrow x=21=x1+y1+z1<x3⇒x<3⇒x=2
因此1y+1z=12=y+zyz⇒2(y+z)−yz=0⇒(y−2)(z−2)=4\frac{1}{y}+\frac{1}{z}=\frac{1}{2}=\frac{y+z}{yz}\Rightarrow 2(y+z)-yz=0\Rightarrow (y-2)(z-2)=4y1+z1=21=yzy+z⇒2(y+z)−yz=0⇒(y−2)(z−2)=4
从而解出了唯一解x=2,y=3,z=6x=2,y=3,z=6x=2,y=3,z=6
于是,有
{6∗x1=x1+x2+x33∗x2=x1+x2+x32∗x3=x1+x2+x3⇒6x1=3x2=2x3\begin{cases} 6*x_1 = x_1+x_2+x_3\\ 3*x_2 = x_1+x_2+x_3\\ 2*x_3 = x_1+x_2+x_3 \end{cases}\\ \Rightarrow 6x_1=3x_2=2x_3 ⎩⎪⎨⎪⎧6∗x1=x1+x2+x33∗x2=x1+x2+x32∗x3=x1+x2+x3⇒6x1=3x2=2x3
令k=x1⇒x2=2k,x3=3kk=x_1\Rightarrow x_2=2k,x_3=3kk=x1⇒x2=2k,x3=3k
所以(x1,x2,x3)=(k,2k,3k),k∈N+(x_1,x_2,x_3)=(k,2k,3k),k\in N^+(x1,x2,x3)=(k,2k,3k),k∈N+,在n≥3n\ge 3n≥3时存在
要满足x1,x2,x3≤nx_1,x_2,x_3\le nx1,x2,x3≤n,所以kkk的取值范围为[1,⌊n3⌋][1,\lfloor\frac{n}{3}\rfloor][1,⌊3n⌋]
答案为⌊n3⌋\lfloor\frac{n}{3}\rfloor⌊3n⌋
void subtask3() {printf( "%lld\n", ( n / 3 ) % mod );
}
m=3,k=2
不妨假设正整数x1<x2<x3x_1<x_2<x_3x1<x2<x3
因为
{(x1+x3)∤x2⇒(x1+x3)∤(x1+x2+x3)(x2+x3)∤x1⇒(x2+x3)∤(x1+x2+x3)\begin{cases} (x_1+x_3)\nmid x_2\Rightarrow (x_1+x_3)\nmid(x_1+x_2+x_3)\\ (x_2+x_3)\nmid x_1\Rightarrow (x_2+x_3)\nmid(x_1+x_2+x_3) \end{cases} {(x1+x3)∤x2⇒(x1+x3)∤(x1+x2+x3)(x2+x3)∤x1⇒(x2+x3)∤(x1+x2+x3)
所以只可能有(x1+x2)∣x3⇒(x1+x2)∣(x1+x2+x3)(x_1+x_2)\mid x_3\Rightarrow (x_1+x_2)\mid(x_1+x_2+x_3)(x1+x2)∣x3⇒(x1+x2)∣(x1+x2+x3)
尝试枚举x1+x2=ix_1+x_2=ix1+x2=i,得到x3x_3x3的取值个数(与m=2,k-1
的求法一样)
再求出iii拆分成x1+x2x_1+x_2x1+x2的拆分方案,利用乘法原理求得最后答案
枚举x1x_1x1后(实际上不可能在代码里枚举)便可唯一确定x2x_2x2的取值
对于和为iii而言:如果x1=i−1x_1=i-1x1=i−1,则x2=1x_2=1x2=1;…\dots… ;如果x1=1x_1=1x1=1,则x2=i−1x_2=i-1x2=i−1,一定有i−1i-1i−1种拆分方法
但是集合{2,3}\{2,3\}{2,3}和集合{3,2}\{3,2\}{3,2}是没有区别的,所以形如a+ba+ba+b的拆分被算了两次,且不合法的形如a+aa+aa+a的拆分也被算了一次
先减去不合法的a+aa+aa+a形式拆分(如果存在的话,显然这种拆分存在当且仅当iii为偶数)
再除以二就是a+ba+ba+b形式的拆分个数了
同样的,我们需要分块来做
答案为∑i=1n⌊ni⌋i−1−[2∣i]2\sum_{i=1}^n\lfloor\frac{n}{i}\rfloor\frac{i-1-[2|i]}{2}i=1∑n⌊in⌋2i−1−[2∣i]
void subtask6() {
/*
(i-1-[2|i])/2
通过打表发现
1->0
2->0
3->1
4->1
...
所以如果是奇数 就是/2
如果是偶数 那么就是/2-1
相当于是两组等差数列
注意l开局的奇偶即可
*/int ans = 0;for( int l = 1, r;l <= n;l = r + 1 ) {r = n / ( n / l );int c = 0;//x首相 y项数 因为有两组所以不用/2了if( l & 1 ) {int len = r - l + 1;int x = l / 2 % mod;int y = len / 2 % mod;c = ( c + ( x + x + y - 1 ) % mod * y % mod ) % mod;if( len & 1 ) c = ( c + r / 2 ) % mod;}else {int x = l / 2 - 1;c = ( c + x % mod ) % mod;int len = r - l;int y = len / 2 % mod;x ++;c = ( c + ( x + x + y - 1 ) % mod * y % mod ) % mod;if( len & 1 ) c = ( c + r / 2 ) % mod;}ans = ( ans + n / r % mod * c % mod ) % mod;}printf( "%lld\n", ( ans + mod ) % mod );
}
m=4,k=1
假设nnn足够大且存在x1<x2<x3<x4→1>1x1>1x2>1x3>1x4x_1<x_2<x_3<x_4\rightarrow 1>\frac{1}{x_1}>\frac{1}{x_2}>\frac{1}{x_3}>\frac{1}{x_4}x1<x2<x3<x4→1>x11>x21>x31>x41,满足
{x1∣(x1+x2+x3+x4)x2∣(x1+x2+x3+x4)x3∣(x1+x2+x3+x4)x4∣(x1+x2+x3+x4)\begin{cases} x_1|(x_1+x_2+x_3+x_4)\\ x_2|(x_1+x_2+x_3+x_4)\\ x_3|(x_1+x_2+x_3+x_4)\\ x_4|(x_1+x_2+x_3+x_4) \end{cases} ⎩⎪⎪⎪⎨⎪⎪⎪⎧x1∣(x1+x2+x3+x4)x2∣(x1+x2+x3+x4)x3∣(x1+x2+x3+x4)x4∣(x1+x2+x3+x4)
不失一般性地假设x<y<z<wx<y<z<wx<y<z<w,满足
{x1+x2+x3+x4=w∗x1x1+x2+x3+x4=z∗x2x1+x2+x3+x4=y∗x3x1+x2+x3+x4=x∗x4\begin{cases} x_1+x_2+x_3+x_4=w*x_1\\ x_1+x_2+x_3+x_4=z*x_2\\ x_1+x_2+x_3+x_4=y*x_3\\ x_1+x_2+x_3+x_4=x*x_4 \end{cases} ⎩⎪⎪⎪⎨⎪⎪⎪⎧x1+x2+x3+x4=w∗x1x1+x2+x3+x4=z∗x2x1+x2+x3+x4=y∗x3x1+x2+x3+x4=x∗x4
则,有1x1+1x2+1x3+1x4=1\frac{1}{x_1}+\frac{1}{x_2}+\frac{1}{x_3}+\frac{1}{x_4}=1x11+x21+x31+x41=1
假设x≥3x\ge 3x≥3,则1x1+1x2+1x3+1x4≤13+14+15+16<1\frac{1}{x_1}+\frac{1}{x_2}+\frac{1}{x_3}+\frac{1}{x_4}\le \frac{1}{3}+\frac{1}{4}+\frac{1}{5}+\frac{1}{6}<1x11+x21+x31+x41≤31+41+51+61<1
假设矛盾,所以1<x<3⇒x=21<x<3\Rightarrow x=21<x<3⇒x=2
假设y≥6y\ge 6y≥6,则1x2+1x3+1x4≤16+17+18<12\frac{1}{x_2}+\frac{1}{x_3}+\frac{1}{x_4}\le \frac{1}{6}+\frac{1}{7}+\frac{1}{8}<\frac{1}{2}x21+x31+x41≤61+71+81<21
假设矛盾,所以2<y<6⇒y=2/3/42<y<6\Rightarrow y=2/3/42<y<6⇒y=2/3/4
- y=3y=3y=3,有(z−6)(w−6)=36→(2,3,7,42);(2,3,8,24);(2,3,9,18);(2,3,10,15)(z-6)(w-6)=36\rightarrow (2,3,7,42);(2,3,8,24);(2,3,9,18);(2,3,10,15)(z−6)(w−6)=36→(2,3,7,42);(2,3,8,24);(2,3,9,18);(2,3,10,15)
- y=4y=4y=4,有(z−4)(w−4)=16→(2,3,5,20);(2,4,6,12)(z-4)(w-4)=16\rightarrow(2,3,5,20);(2,4,6,12)(z−4)(w−4)=16→(2,3,5,20);(2,4,6,12)
- y=5y=5y=5,有(3z−10)(3w−10)=100→∅(3z-10)(3w-10)=100\rightarrow \empty(3z−10)(3w−10)=100→∅
所以整理一下,结果为
(x1,x2,x3,x4)=(k,2k,3k,6k);;(k,2k,6k,9k);;(k,3k,8k,12k);;(k,4k,5k,10k);;(k,6k,14k,21k);;(2k,3k,10k,15k)(x_1,x_2,x_3,x_4)=(k,2k,3k,6k);;(k,2k,6k,9k);;(k,3k,8k,12k);;(k,4k,5k,10k);;(k,6k,14k,21k);;(2k,3k,10k,15k)(x1,x2,x3,x4)=(k,2k,3k,6k);;(k,2k,6k,9k);;(k,3k,8k,12k);;(k,4k,5k,10k);;(k,6k,14k,21k);;(2k,3k,10k,15k)
(反解过程,上面有示范,这里不再展开计算)
所以在n≥6n\ge 6n≥6的时候才会全都成立,当n=4/5n=4/5n=4/5就手玩硬算
答案为
{1n=4,5⌊n6⌋+⌊n9⌋+⌊n10⌋+⌊n12⌋+⌊n15⌋+⌊n21⌋n≥6\begin{cases} 1\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\ n=4,5\\ \lfloor\frac{n}{6}\rfloor+\lfloor\frac{n}{9}\rfloor+\lfloor\frac{n}{10}\rfloor+\lfloor\frac{n}{12}\rfloor+\lfloor\frac{n}{15}\rfloor+\lfloor\frac{n}{21}\rfloor\quad n\ge 6 \end{cases} {1 n=4,5⌊6n⌋+⌊9n⌋+⌊10n⌋+⌊12n⌋+⌊15n⌋+⌊21n⌋n≥6
void subtask4() {if( n == 4 or n == 5 ) printf( "1\n" );else printf( "%lld\n", ( n / 6 % mod + n / 9 % mod + n / 10 % mod + n / 12 % mod + n / 15 % mod + n / 21 % mod ) % mod );
}
m=4,k=2
不妨假设正整数x1<x2<x3<x4x_1<x_2<x_3<x_4x1<x2<x3<x4,则有
{(x2+x4)∤(x1+x3)⇒(x2+x4)∤(x1+x2+x3+x4)(x3+x4)∤(x1+x2)⇒(x3+x4)∤(x1+x2+x3+x4)\begin{cases} (x_2+x_4)\nmid(x_1+x_3)\Rightarrow (x_2+x_4)\nmid(x_1+x_2+x_3+x_4)\\ (x_3+x_4)\nmid(x_1+x_2)\Rightarrow (x_3+x_4)\nmid(x_1+x_2+x_3+x_4) \end{cases} {(x2+x4)∤(x1+x3)⇒(x2+x4)∤(x1+x2+x3+x4)(x3+x4)∤(x1+x2)⇒(x3+x4)∤(x1+x2+x3+x4)
假设nnn足够大且存在x1<x2<x3<x4x_1<x_2<x_3<x_4x1<x2<x3<x4,满足
{(x1+x2)∣(x1+x2+x3+x4)⇒(x1+x2)∣(x3+x4)(x1+x3)∣(x1+x2+x3+x4)⇒(x1+x3)∣(x2+x4)(x1+x4)∣(x1+x2+x3+x4)⇒x1+x4=x2+x3(x2+x3)∣(x1+x2+x3+x4)⇒x1+x4=x2+x3\begin{cases} (x_1+x_2)\mid(x_1+x_2+x_3+x_4)\Rightarrow (x_1+x_2)\mid (x_3+x_4)\\ (x_1+x_3)\mid(x_1+x_2+x_3+x_4)\Rightarrow (x_1+x_3)\mid (x_2+x_4)\\ (x_1+x_4)\mid(x_1+x_2+x_3+x_4)\Rightarrow x_1+x_4=x_2+x_3\\ (x_2+x_3)\mid(x_1+x_2+x_3+x_4)\Rightarrow x_1+x_4=x_2+x_3\\ \end{cases} ⎩⎪⎪⎪⎨⎪⎪⎪⎧(x1+x2)∣(x1+x2+x3+x4)⇒(x1+x2)∣(x3+x4)(x1+x3)∣(x1+x2+x3+x4)⇒(x1+x3)∣(x2+x4)(x1+x4)∣(x1+x2+x3+x4)⇒x1+x4=x2+x3(x2+x3)∣(x1+x2+x3+x4)⇒x1+x4=x2+x3
因为x2<x3<x4x_2<x_3<x_4x2<x3<x4,所以x2+x4x_2+x_4x2+x4不可能大于等于x4x_4x4的三倍,只能是x4x_4x4的两倍多(毕竟x4x_4x4要+x1+x_1+x1)
设s(x1+x3)=x2+x4=2x2+x3−x1<3(x1+x3)s(x_1+x_3)=x_2+x_4=2x_2+x_3-x_1<3(x_1+x_3)s(x1+x3)=x2+x4=2x2+x3−x1<3(x1+x3)
所以1<s<3⇒s=21<s<3\Rightarrow s=21<s<3⇒s=2
设t(x1+x2)=x3+x4=5x2−7x1<5(x1+x2)t(x_1+x_2)=x_3+x_4=5x_2-7x_1<5(x_1+x_2)t(x1+x2)=x3+x4=5x2−7x1<5(x1+x2)
所以2=s<t<5⇒t=3/42=s<t<5\Rightarrow t=3/42=s<t<5⇒t=3/4
推出(x1,x2,x3,x4)=(k,5k,7k,11k);;(k,11k,19k,20k)(x_1,x_2,x_3,x_4)=(k,5k,7k,11k);;(k,11k,19k,20k)(x1,x2,x3,x4)=(k,5k,7k,11k);;(k,11k,19k,20k)
在n≥11n\ge 11n≥11时,满足假设条件,n<11n<11n<11的情况直接手玩
{1n=4,5,63n=76n=89n=910n=10⌊n11⌋+⌊n29n≥11\begin{cases} 1\quad\quad\quad\quad\quad\ n=4,5,6\\ 3\quad\quad\quad\quad\quad\ n=7\\ 6\quad\quad\quad\quad\quad\ n=8\\ 9\quad\quad\quad\quad\quad\ n=9\\ 10\quad\quad\quad\quad\ \ \ n=10\\ \lfloor\frac{n}{11}\rfloor+\lfloor\frac{n}{29}\quad n\ge 11 \end{cases} ⎩⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎧1 n=4,5,63 n=76 n=89 n=910 n=10⌊11n⌋+⌊29nn≥11
void subtask5() {if( n == 4 or n == 5 or n == 6 ) printf( "1\n" );else if( n == 7 ) printf( "3\n" );else if( n == 8 ) printf( "6\n" );else if( n == 9 ) printf( "9\n" );else if( n == 10 ) printf( "10\n" );else printf( "%lld\n", ( n / 11 % mod + n / 29 % mod ) % mod );
}
m=4,k=3
不妨假设正整数x1<x2<x3<x4x_1<x_2<x_3<x_4x1<x2<x3<x4,有
{(x1+x2+x4)∤x3⇒(x1+x2+x4)∤(x1+x2+x3+x4)(x1+x3+x4)∤x2⇒(x1+x3+x4)∤(x1+x2+x3+x4)(x3+x2+x4)∤x1⇒(x3+x2+x4)∤(x1+x2+x3+x4)\begin{cases} (x_1+x_2+x_4)\nmid x_3\Rightarrow (x_1+x_2+x_4)\nmid(x_1+x_2+x_3+x_4)\\ (x_1+x_3+x_4)\nmid x_2\Rightarrow (x_1+x_3+x_4)\nmid(x_1+x_2+x_3+x_4)\\ (x_3+x_2+x_4)\nmid x_1\Rightarrow (x_3+x_2+x_4)\nmid(x_1+x_2+x_3+x_4)\\ \end{cases} ⎩⎪⎨⎪⎧(x1+x2+x4)∤x3⇒(x1+x2+x4)∤(x1+x2+x3+x4)(x1+x3+x4)∤x2⇒(x1+x3+x4)∤(x1+x2+x3+x4)(x3+x2+x4)∤x1⇒(x3+x2+x4)∤(x1+x2+x3+x4)
所以只可能有
(x1+x2+x3)∣x4⇒(x1+x2+x3)∣(x1+x2+x3+x4)(x_1+x_2+x_3)\mid x_4\Rightarrow (x_1+x_2+x_3)\mid(x_1+x_2+x_3+x_4)(x1+x2+x3)∣x4⇒(x1+x2+x3)∣(x1+x2+x3+x4)
通过枚举i=x1+x2+x3i=x_1+x_2+x_3i=x1+x2+x3,确定x4x_4x4的个数n−in-in−i,再计算iii拆分的方案,乘法原理即可求得最后答案
考虑计算拆分方案:假想枚举x1x_1x1,则a+b+ca+b+ca+b+c的形式会被计算666次,a+a+ba+a+ba+a+b的形式会被计算333次,a+a+aa+a+aa+a+a的形式会被计算111次
当x1=1,2,...i−2x_1=1,2,...i-2x1=1,2,...i−2,则x2=[1,i−2],...,[1,1]x_2=[1,i-2],...,[1,1]x2=[1,i−2],...,[1,1]
所以方案数为(i−2)+(i−1)+...+1=(i−1)(i−2)2(i-2)+(i-1)+...+1=\frac{(i-1)(i-2)}{2}(i−2)+(i−1)+...+1=2(i−1)(i−2)
我们如果能减去这些不合法的形式,再除以六就是拆分的最终方案数了
显然,a+a+ba+a+ba+a+b的形式能被计算到,当且仅当a∈[1,⌊i−12⌋]a\in [1,\lfloor\frac{i-1}{2}\rfloor]a∈[1,⌊2i−1⌋]。a+a+aa+a+aa+a+a的形式能被计算到,当且仅当i=3ai=3ai=3a
我们可以再假想枚举x2x_2x2,来减掉a+a+ba+a+ba+a+b的形式, 即−3⌊i−12⌋-3\lfloor\frac{i-1}{2}\rfloor−3⌊2i−1⌋,将这个暴力拆开与上面的合并,则会发现iii为偶数的时候,多减了32\frac{3}{2}23,要加回来
但这样a+a+aa+a+aa+a+a形式就会被减去三次,多减了两次,需要加回来2[3∣i]2[3|i]2[3∣i](别忘了这个形式存在的前提是i=3ai=3ai=3a),这个的基础是最后总数/6/6/6,但是答案的表示是/12/12/12
所以上面分子写的是444的系数
所以答案是
{1n=45n=5∑i=1n⌊ni⌋i2−6i+5+3[2∣i]+4[3∣i]12n≥6\begin{cases} 1\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\ \ \ n=4\\ 5\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\ \ \ n=5\\ \sum_{i=1}^n\lfloor\frac{n}{i}\rfloor\frac{i^2-6i+5+3[2|i]+4[3|i]}{12}\quad n\ge 6 \end{cases} ⎩⎪⎨⎪⎧1 n=45 n=5∑i=1n⌊in⌋12i2−6i+5+3[2∣i]+4[3∣i]n≥6
但是又因为涉及分块,所以计算一段区间内2,32,32,3的倍数个数,简直要命,主要是左端点开头,救命!!
void subtask7() {if( n == 4 ) printf( "1\n" );else if( n == 5 ) printf( "5" );else {int ans = 0, lst = 0, inv2 = qkpow( 2, mod - 2 ), inv3 = qkpow( 3, mod - 2 ), inv12 = qkpow( 12, mod - 2 );for( int l = 1, r;l <= n;l = r + 1 ) {r = ( n / ( n / l ) );int len = r - l + 1;int now = r % mod * ( ( r + 1 ) % mod ) % mod * ( ( r % mod * 2 + 1 ) % mod ) % mod * inv2 % mod * inv3 % mod;int c = ( now - lst + mod ) % mod;c = ( c - ( l % mod + r % mod ) % mod * ( len % mod ) % mod * inv2 % mod * 6 % mod + mod ) % mod;c = ( c + len % mod * 5 % mod + mod ) % mod;lst = now;c = ( c + ( len / 2 % mod + ( len & 1 and ! ( l & 1 ) ) ) * 3 % mod ) % mod;c = ( c + ( len / 3 % mod + ( ( len % 3 != 0 ) and ( ( l % 3 == 0 ) or ( len % 3 == 2 and l % 3 == 2 ) ) ) ) * 4 % mod ) % mod;c = c * inv12 % mod;ans = ( ans + n / r % mod * c % mod ) % mod;}printf( "%lld\n", ans );}
}
code
#include <cstdio>
#include <cmath>
using namespace std;
#define mod 1000000007
#define int long long
int n, m, k;int qkpow( int x, int y ) {int ans = 1;while( y ) {if( y & 1 ) ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans;
}void subtask1() {int ans = 1;for( int i = n;i > n - m;i -- )ans = i % mod * ans % mod;for( int i = 1;i <= m;i ++ )ans = ans * qkpow( i, mod - 2 ) % mod;printf( "%lld\n", ans );
}void subtask2() {int ans = 0;for( int r = n, l;r > 0;r = l - 1 ) {if( r == 1 ) break;l = n / ( n / r + 1 ) + 1;int t = n / r;ans = ( ans + t % mod * ( r - l + 1 ) % mod ) % mod;}printf( "%lld\n", ans );
}void subtask3() {printf( "%lld\n", ( n / 3 ) % mod );
}void subtask4() {if( n == 4 or n == 5 ) printf( "1\n" );else printf( "%lld\n", ( n / 6 % mod + n / 9 % mod + n / 10 % mod + n / 12 % mod + n / 15 % mod + n / 21 % mod ) % mod );
}void subtask5() {if( n == 4 or n == 5 or n == 6 ) printf( "1\n" );else if( n == 7 ) printf( "3\n" );else if( n == 8 ) printf( "6\n" );else if( n == 9 ) printf( "9\n" );else if( n == 10 ) printf( "10\n" );else printf( "%lld\n", ( n / 11 % mod + n / 29 % mod ) % mod );
}void subtask6() {int ans = 0;for( int l = 1, r;l <= n;l = r + 1 ) {r = n / ( n / l );int c = 0;if( l & 1 ) {int len = r - l + 1;int x = l / 2 % mod;int y = len / 2 % mod;c = ( c + ( x + x + y - 1 ) % mod * y % mod ) % mod;if( len & 1 ) c = ( c + r / 2 ) % mod;}else {int x = l / 2 - 1;c = ( c + x % mod ) % mod;int len = r - l;int y = len / 2 % mod;x ++;c = ( c + ( x + x + y - 1 ) % mod * y % mod ) % mod;if( len & 1 ) c = ( c + r / 2 ) % mod;}ans = ( ans + n / r % mod * c % mod ) % mod;}printf( "%lld\n", ( ans + mod ) % mod );
}void subtask7() {if( n == 4 ) printf( "1\n" );else if( n == 5 ) printf( "5" );else {int ans = 0, lst = 0, inv2 = qkpow( 2, mod - 2 ), inv3 = qkpow( 3, mod - 2 ), inv12 = qkpow( 12, mod - 2 );for( int l = 1, r;l <= n;l = r + 1 ) {r = ( n / ( n / l ) );int len = r - l + 1;int now = r % mod * ( ( r + 1 ) % mod ) % mod * ( ( r % mod * 2 + 1 ) % mod ) % mod * inv2 % mod * inv3 % mod;int c = ( now - lst + mod ) % mod;c = ( c - ( l % mod + r % mod ) % mod * ( len % mod ) % mod * inv2 % mod * 6 % mod + mod ) % mod;c = ( c + len % mod * 5 % mod + mod ) % mod;lst = now;c = ( c + ( len / 2 % mod + ( len & 1 and ! ( l & 1 ) ) ) * 3 % mod ) % mod;c = ( c + ( len / 3 % mod + ( ( len % 3 != 0 ) and ( ( l % 3 == 0 ) or ( len % 3 == 2 and l % 3 == 2 ) ) ) ) * 4 % mod ) % mod;c = c * inv12 % mod;ans = ( ans + n / r % mod * c % mod ) % mod;}printf( "%lld\n", ans );}
}signed main() {freopen( "vegetable.in", "r", stdin );freopen( "vegetable.out", "w", stdout );scanf( "%lld %lld %lld", &n, &m, &k );if( m == k ) subtask1();else if( m == 2 and k == 1 ) subtask2();else if( m == 3 and k == 1 ) subtask3();else if( m == 4 and k == 1 ) subtask4();else if( m == 4 and k == 2 ) subtask5();else if( m == 3 and k == 2 ) subtask6();else subtask7();return 0;
}