又是先开T3的做题顺序,搞我心态。以后我必须先看看题了。

整数拆分

定义 \(f_m(n)\) 表示将 \(n\) 表示为若干 \(m\) 的非负整数次幂的和的方案数。例如,当 \(m = 2\) 的时候,\(f_2(4) = 4\),一共有 \(\{1, 1, 1, 1\}, \{1, 1, 2\}, \{2, 2\}, \{4\}\) 这 \(4\) 种方案。

定义 \(g^k_m(n)\) 为 \(k\) 个 \(f_m(n)\) 卷积起来的结果,即:

\[g^k_m(n) = \begin{cases}
f_m(n) & k = 1\\
\sum_{i=0}^n(g_m^{k−1}(i) × f_m(n − i)) & \text{otherwise}
\end{cases}
\]

给定 \(n, m, k\),请求出 \((\sum^n_{i=0} g^k_m(i)) \mod 10^9 + 7\)。

对于所有数据,满足 \(0 ≤ n ≤ 10^{18}, 2 ≤ m ≤ 10^{18}, 1 ≤ k ≤ 20\)。

题解

考场上推生成函数,然而即使推出来了答案的式子我还是不知道怎么做……结果是个DP。

\[f_m=\frac{1}{1-x}\frac{1}{1-x^m}\dots\frac{1}{1-x^{m^{\lfloor\log_mn\rfloor}}}\\
g_m^k=\left(\frac{1}{1-x}\right)^k \left(\frac{1}{1-x^m}\right)^k \dots \left(\frac{1}{1-x^{m^{\lfloor\log_mn\rfloor}}}\right)^k
\]

由于答案是对 \(\sum_{i=0}^ng_m^k(i)\) 求和,所以再乘以一项 \(\frac{1}{1-x}\),那么

\[ans=\left(\frac{1}{1-x}\right)^{k+1} \left(\frac{1}{1-x^m}\right)^k \dots \left(\frac{1}{1-x^{m^{\lfloor\log_mn\rfloor}}}\right)^k [x^n]
\]

然后我就开始想怎么用广义二项式定理推通项公式的事情了。

我想到了对 \(n\) 进行 \(m\) 进制拆分,但是推贡献的时候错了一步。用 \(1\) 去凑 \(2m\) 的方案数并不等于用 \(1\) 去凑 \(m\) 的方案数的平方。

当时我以为有这个关系,然后式子化成了

\[ans_1=\frac{1}{1-ax^m} \left(\frac{1}{1-x^m}\right)^k [x^{m_1}]
\]

然后我就开始仿造斐波那契数列的通项公式的构造过程,列了个方程

\[\frac{t_0}{1-ax^m} + \frac{t_1}{1-x^m} + \frac{t_2x}{1-x^m} + \dots + \frac{1}{t_kx^{k-1}}=
\frac{1}{1-ax^m} \left(\frac{1}{1-x^m}\right)^k
\]

然后我发现它挺好解的,于是写了个高斯消元。最终发现推错的那一步时心态爆炸。

Subtask2

\(n\leq 1000\)

\[f(n)=\begin{cases}
f(n-1) & n\mod m\neq 0\\
f(n-1)+f(n/m) & n\mod m=0
\end{cases}
\]

这个继整数拆分以后的DP方程也很妙啊。

Subtask4

\(k=1\)

可以用的数字一共有 \(1,m,m^2,m^3\dots\) 共 \(\lfloor\log_mn\rfloor\) 个。

令 \(f[i][j]\) 表示用了前 \(i\) 个数字,当前和为 \(j\) 的方案数。

令 \(j=k* m^(i-1)+r,r< m^(i-1)\)

注意到后面的都是前面的倍数,所以无论后面的数字如何选择,都不可能改变 \(r\) 的值,因此可能被用到的 \(j\) 的 一定是 \(k* m^(i-1)+n\mod m^(i-1)\)。

令 \(h[i][j]\) 表示用了前 \(i\) 个数字,当前数字和为 \(j* m^(i-1)+n\mod m^(i-1)\) 的方案。

这样 \(j\) 这一维还是太大。

通过观察和归纳证明,可以得到,对于确定的 \(i\),\(h[i][j]\) 是一个关于 \(j\) 的 \(i\) 次多项式。

于是我们可以只保留前 \(i+1\) 项 DP 值,转移使用插值。

\[h[i][j]=f[i][j\cdot a_i+n\mod a_i]\\
=\sum_{k=0}^jf[i-1][k\cdot a_i+n\mod a_i]\\
=\sum_{k=0}^jf[i-1][k\frac{a_i}{a_{i-1}}a_{i-1}+\left\lfloor\frac{n \mod a_i}{a_{i-1}}\right\rfloor\cdot a_{i-1}+(n\mod a_i)\mod a_{i-1}]\\
=\sum_{k=0}^jh[i-1][k\frac{a_i}{a_{i-1}}+\left\lfloor\frac{n \mod a_i}{a_{i-1}}\right\rfloor]
\]

一共 \(O(\log n)\) 个因数,每次需要做一次插值,\(O(\log n)\) 次求值,复杂度 \(O(\log^3 n)\)。

CO int N=2000+10;
int fac[N],ifac[N]; struct polynomial{
int n,y[N];
int coef[N],pre[N],suf[N]; void init(){
for(int i=1;i<=n;++i){
int sum=mul(ifac[i-1],mul(ifac[n-i],y[i]));
coef[i]=(n-i)&1?mod-sum:sum;
}
}
int calc(int x){
if(x<=n-1) return y[x+1];
pre[0]=1;
for(int i=1;i<=n;++i) pre[i]=mul(pre[i-1],add(x,mod-(i-1)));
suf[n+1]=1;
for(int i=n;i>=1;--i) suf[i]=mul(suf[i+1],add(x,mod-(i-1)));
int ans=0;
for(int i=1;i<=n;++i) ans=add(ans,mul(coef[i],mul(pre[i-1],suf[i+1])));
return ans;
}
}h[N]; LL pw[N];int lg;
LL a[N];int cnt; int main(){
freopen("split.in","r",stdin),freopen("split.out","w",stdout);
LL n=read<LL>(),m=read<LL>();
int K=read<int>(); lg=0,pw[0]=1;
for(;pw[lg]<=n/m;++lg) pw[lg+1]=pw[lg]*m;
cnt=0,a[0]=1;
for(int i=0;i<=lg;++i)
for(int j=1;j<=K;++j) a[++cnt]=pw[i];
fac[0]=1;
for(int i=1;i<=cnt;++i) fac[i]=mul(fac[i-1],i);
ifac[cnt]=fpow(fac[cnt],mod-2);
for(int i=cnt-1;i>=0;--i) ifac[i]=mul(ifac[i+1],i+1); h[0].n=1,h[0].y[1]=1;
h[0].init();
for(int i=1;i<=cnt;++i){
h[i].n=i+1;
LL r=n%a[i]/a[i-1];
for(int j=0;j<=i;++j){
h[i].y[j+1]=h[i-1].calc((a[i]/a[i-1]*j+r)%mod);
h[i].y[j+1]=add(h[i].y[j],h[i].y[j+1]);
}
h[i].init();
}
printf("%d\n",h[cnt].calc((n/a[cnt])%mod));
return 0;
}

我觉得如果我能猜到那个生成函数的系数是多项式的话,我还是做得出来的。但毕竟见识太少,我只会中规中矩的方法,不会直接想到拉格朗日插值和BM算法。

多项式证明

首先 \(\frac{1}{1-x}\) 的系数是多项式。

通过打表找规律,两个系数是多项式的生成函数卷积后的生成函数的系数也是多项式。\(n\) 次的多项式乘以 \(m\) 次的多项式得到的是 \(n+m+1\) 次的多项式。

那么 \((\frac{1}{1-x})^{k+1}\) 就是一个 \(k\) 次多项式。往 \(\frac{1}{1-x^m}\) 合并的时候,我们只会用 \(x\) 的次数是 \(m\) 的自然数倍的项,分离常数后它还是一个 \(k\) 次多项式;但是 \(\frac{1}{1-x^m}\) 分离常数后变成了 \(0\) 次多项式,所以 \((\frac{1}{1-x})^{k+1} (\frac{1}{1-x^m})^k\) 就是一个 \(2k\) 次多项式。

如此归纳下去,就可证明那个 DP 状态一直是多项式了。

简单计数

给定一个长度为 \(n\) 的序列 \(s\)。共询问 \(m\) 次,每次询问给定一个数字 \(k\) 和一个固定长度 \(l\),以及 \(k\) 个 整数 \(x_1, x_2, \dots, x_k\)。请求出,如果将区间 \([x_1, x_1 + l − 1],[x_2, x_2 + l − 1],\dots,[x_k, x_k + l − 1]\) 按照顺序前后 拼接在一起得到的序列中,有多少回文子串,序列从 \(1\) 开始编号。回文子串的定义是,这个序列从前往 后和从后往前是一样的。

对于所有数据,满足 \(n ≤ 10^5 , m ≤ 10^5 , ∑k ≤ 10^5 , ∑k × l ≤ 10^9 , x_i + l − 1 ≤ n, 1 ≤ s_i ≤ n\)。

题解

咕咕咕。

排序

给出一个长度为 \(n\) 的整数序列,你能够使用的操作只有 \(\text{rev}(l, r)\),表示将闭区间 \([l, r]\) 内的数字翻转,需要的代价是 \(r − l + 1\), 你需要在 \(4 × 10^6\) 的代价内最大化最终序列的 LIS 长度,LIS 表示最长上升子序列。

只有你使用的操作的代价不超过限制,并且最终得到的序列的 LIS 和理论上能够得到的最大值一样 的时候,才可以得分。

对于所有数据,满足 \(n ≤ 32000, 0 ≤ 序列中的数字 ≤ 32000\)。

题解

题目让你最大化LIS,然而其实完全可以排好序……所以说我们要有大胆猜结论的能力。并且这道题是考场上AC人数最多的。

Subtask3

考虑 01 序列如何排序。其实归并排序就可以,每次我们把左区间所有的 1 和右区间所有的 0 ,交换一下。

0101
0011

值域 \([0,5]\) 同理,我们可以每次把一种数字分出来。

012345012345
012344321055
001234432155
001123443255
001122344355
001122334455

复杂度 \(O(6n\log n)\)。

Subtask4

值域较大,对所有数字再进行一次分治即可。

具体而言,就是按位从高到低做。有点像倒着的基数排序。

CO int N=32000+10;
int a[N];
vector<pair<int,int> > sol; void reverse(int l,int r){
reverse(a+l,a+r+1);
sol.push_back(make_pair(l,r));
}
void sol01(int l,int r,int w){
if(l==r) return;
int mid=(l+r)>>1;
sol01(l,mid,w),sol01(mid+1,r,w);
int ql=0;
for(int i=mid;i>=l;--i)
if(a[i]>>w&1) ql=i;
int qr=0;
for(int i=mid+1;i<=r;++i)
if(~a[i]>>w&1) qr=i;
if(ql and qr) reverse(ql,qr);
}
void solve(int l,int r,int w){
if(l>r or w==-1) return;
sol01(l,r,w);
int mid=0;
for(int i=l;i<=r;++i)
if(~a[i]>>w&1) mid=i;
if(!mid) solve(l,r,w-1);
else solve(l,mid,w-1),solve(mid+1,r,w-1);
}
int main(){
freopen("rev.in","r",stdin),freopen("rev.out","w",stdout);
int n=read<int>();
for(int i=1;i<=n;++i) read(a[i]);
solve(1,n,14);
printf("%zd\n",sol.size());
for(int i=0;i<(int)sol.size();++i)
printf("%d %d\n",sol[i].first,sol[i].second);
return 0;
}

test20191205 WC模拟赛的更多相关文章

  1. NOI.AC WC模拟赛

    4C(容斥) http://noi.ac/contest/56/problem/25 同时交换一行或一列对答案显然没有影响,于是将行列均从大到小排序,每次处理限制相同的一段行列(呈一个L形). 问题变 ...

  2. NOIp2018模拟赛四十二

    今天看标题终于回到了“NOIP模拟赛”,十分高兴啊! 然后一打开题目: ********** 所以今天又是一场NOIPlus模拟赛(微笑) 成绩:0+70+0=70 A题想了个贪心被myh两分钟cha ...

  3. 冲刺$\mathfrak{CSP-S}$集训模拟赛总结

    开坑.手懒并不想继续一场考试一篇文. 既没必要也没时间侧边栏的最新随笔题解反思相间也丑 而且最近越来越懒了竟然都不写题解了……开坑也是为了督促自己写题解. 并不想长篇大论.简要题解也得写啊QAQ. 目 ...

  4. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  5. NOI模拟赛 Day1

    [考完试不想说话系列] 他们都会做呢QAQ 我毛线也不会呢QAQ 悲伤ING 考试问题: 1.感觉不是很清醒,有点困╯﹏╰ 2.为啥总不按照计划来!!! 3.脑洞在哪里 4.把模拟赛当作真正的比赛,紧 ...

  6. NOIP第7场模拟赛题解

    NOIP模拟赛第7场题解: 题解见:http://www.cqoi.net:2012/JudgeOnline/problemset.php?page=13 题号为2221-2224. 1.car 边界 ...

  7. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  8. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  9. 小奇模拟赛9.13 by hzwer

    2015年9月13日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿(explo) [题目背景] 小奇要开采一些矿物,它驾驶着一台带有钻头(初始能力值w)的飞船,按既定路线依次飞 ...

随机推荐

  1. [ARM-Linux]Linux-MATLAB安装

    说明 网上关于caffe的安装教程非常多,但是关于每一步是否操作成功,出现了什么样的错误又该如何处理没有给出说明.因为大家的操作系统的环境千差万别,按照博客中的教程一步步的安装,最后可能失败--这是很 ...

  2. 034 通过域名访问服务器或本地的图片资源---switchhost+nginx

    1.修改host解析 2.使用Nginx代理,实现域名访问 进入Nginx的安装路径E:\toolsoftware\nginx-1.14.0\nginx-1.14.0\conf,修改 添加如下内容: ...

  3. C++ 结构体、模板、类、重载初使用

    目的:需要几个缓存用的数组900*750 首先定义一个模板<参数数据类型,参数1,参数2> 定义一个class类 名字自己取ap_uint0 下面是公用的数组模板[lrow][lcol] ...

  4. Linux设置SSH隧道连接

    因为安全考虑,服务器防火墙对某些端口进行了限制,原先通过客户端工具可以连接的端口,现在不能连接了,需要通过设置SSH隧道才可以,记录如下.

  5. GoldenDict(for Linux)配置无道词典

    引言 我原来写过一篇博客:(离线)英语词典软件推荐,个人比较喜欢的就是GoldenDict词典.不仅仅是因为它是免费开源的多平台程序,更重要的是支持丰富的原版词典(下文给出了下载链接).本文主要针对其 ...

  6. 推送一个docker 使用阿里docker hub

    阿里docker hub 地址 打开容器镜像服务页https://cr.console.aliyun.com/cn-qingdao/namespaces 这个是我的私有库 配置加速 我这边用的也是阿里 ...

  7. kafka Enabling Kerberos Authentication

    CDK 2.0 and higher Powered By Apache Kafka supports Kerberos authentication, but it is supported onl ...

  8. Visual Studio 技巧

    Visual Studio 技巧 1 常用设置 2 常用快捷键 2.1 系统默认快捷键 2.2 自定义快捷键 3 修复系统错误 1 常用设置 Text Editor -> All Languag ...

  9. 获取Excel

    默认Excel文档为 代码如下   需要下载  "EPPlus.Core" var file = Directory.GetCurrentDirectory() + "\ ...

  10. 英语Barklyite红宝石barklyite单词

    红宝石的英文名称为barklyite或Ruby,源于拉丁文 Ruber,意思是红色.红宝石的日文名称为ルビー.红宝石的矿物名称为刚玉.(注:除红宝石外,其他颜色的刚玉都属于蓝宝石.如粉红色刚玉被称为粉 ...