洛谷题面传送门

一道挺有意思的题,现场切掉还是挺有成就感的。

首先看到区间操作我们可以想到差分转换,将区间操作转化为差分序列上的一个或两个单点操作,具体来说我们设 \(b_i=a_{i+1}-a_i\),那么对于一次形如 \(\forall i\in[l,r],a_i\leftarrow a_i+x\) 的操作三元组 \((l,r,x)\),我们有:

  • \(l=1,r=n\),等于啥也没干,那么我们显然不会选择这样的区间进行操作,否则就会浪费一次操作次数,所以我们 duck 不必考虑这种情况。
  • \(l=1,r\ne n\):相当于令 \(b_{r}\leftarrow b_r-x\)
  • \(l\ne 1,r=n\):相当于令 \(b_{l-1}\leftarrow b_{l-1}+x\)
  • \(l\ne 1,r\ne n\):相当于令 \(b_{l-1}\leftarrow b_{l-1}+x,b_r\leftarrow b_r-x\)

于是问题转化为:给定长度为 \(n-1\) 的差分序列,每次可以进行以下两种操作之一:修改一个单点的值,或者指定三个整数 \(x,y,z\),将 \(b_x\) 改为 \(b_x+z\),\(b_y\) 改为 \(b_y-z\),最少需要多少次操作才能将所有数变为 \(0\)。

直接处理不太容易,因此考虑挖掘一些性质。做过这道题的同学应该不难想到,我们可以在每次操作的两个点之间连一条边,如果咱们操作的是一个单点那么就连一条自环,这样显然会得到一张点数为 \(n-1\),边数等于操作次数的图。那么有一个性质:在最优策略连出的图中,对于每个连通块 \((V',E')\),记 \(S=\sum\limits_{x\in V'}b_x\),有

  • 如果 \(S=0\),那么该连通块必然是一棵树,耗费 \(|V'|-1\) 次操作。
  • 如果 \(S\ne 0\),那么该连通块必然是一棵树加一个自环,耗费 \(|V'|\) 次操作。

证明不会,感性理解一下即可

观察到这个性质之后,求解第一问就易如反掌了,注意到 \(n\) 很小,因此考虑状压,记 \(dp_S\) 表示将 \(S\) 中的元素变为 \(0\) 的最少操作次数,枚举子集转移即可,复杂度 \(3^{n-1}\)。

接下来考虑第二问,显然每次操作都是不同的,因此我们可以只用考虑操作方案的集合有哪些,最后乘个操作次数的阶乘即可。其次,如果我们能够知道对于一个连通块而言,将它按照最优策略变为 \(0\) 的方案数,我们就能用乘法原理一边 DP 一遍记录将每个集合变为 \(0\) 的最优策略的方案数了。因此考虑将每个集合变为 \(0\) 的方案数,还是分 \(S=0\) 和 \(S\ne 0\) 两种情况处理:

  • \(S=0\),那么该连通块是一棵无根树,那么可以很自然地猜到应该跟什么有标号树计数有关,Prufer 序列算一算结果是 \(|V'|^{|V'|-2}\),事实上结论也的确如此,这里稍微口胡一下证明:显然一个操作集合唯一对应一棵树,而对于一棵无根树而言,能够得到它的操作集合也是唯一的,证明可以通过构造方案说明:我们假设这棵树中编号最大(其实大不大无所谓,只要形成一个严格的偏序关系即可)的叶子节点为 \(u\),与其相连的点为 \(v\),那么我们必须让 \(u\) 的权值变为 \(0\),因为否则进行完此次操作之后,点 \(u\) 就孤立了,无法再次通过两点的操作变回 \(0\) 了,因此这次操作 \(u\) 的权值必须减去 \(a_u\),\(v\) 的权值也就必然加上 \(a_u\),如此进行下去直到还剩一个点为止,而由于该连通块中权值之和为 \(0\),因此最终剩下的那个点权值也是 \(0\),故我们构造出的方案合法。又因为我们每一次操作唯一,因此操作集合唯一;如果我们改变下操作的边集的顺序那么显然操作集合不会变,因此操作集合与无根树形成双射关系,证毕。
  • \(S\ne 0\),其实不过是在无根树的基础上加了一个自环,加这个自环的侯选位置总共有 \(|V'|\) 个,再加上对于这个自环而言有两个区间能够改变差分序列上这个点的值(假设我们要改变 \(b_x\),那么我们可以操作 \([1,x]\),也可以操作 \([x+1,n]\)),因此还需乘个 \(2\),总方案数 \(2|V'|^{|V'|-1}\),如果你力求极致、追求严谨,那么也可以仿照 \(S=0\) 的证明方式。

时间复杂度 \(\mathcal O(3^{n-1})\)。

using namespace fastio;
const int MAXN=18;
const int MAXP=1<<17;
const int MOD=1e9+7;
const int INF=0x3f3f3f3f;
int n,a[MAXN+3],b[MAXN+3],m=0,c[MAXN+3],cnt[MAXP+5],fac[MAXN+5];
int f[MAXN+5],g[MAXN+5];
ll sum[MAXP+5];pii dp[MAXP+5];
inline int high(int x){return (!x)?-1:(31-__builtin_clz(x));}
int qpow(int x,int e){
int ret=1;
for(;e;e>>=1,x=1ll*x*x%MOD) if(e&1) ret=1ll*ret*x%MOD;
return ret;
}
void upd(pii &x,pii y,int v,int z){
return (x.fi<y.fi+v)?void():(((x.fi==y.fi+v)?(x.se=(x.se+1ll*y.se*z)%MOD):
(x.fi=y.fi+v,x.se=1ll*y.se*z%MOD)),void());
}
int main(){
scanf("%d",&n);dp[0]=mp(0,1);
for(int i=(fac[0]=1);i<=n;i++) fac[i]=1ll*fac[i-1]*i%MOD;
for(int i=2;i<=n;i++) g[i]=qpow(i,i-2),f[i]=2ll*g[i]*i%MOD;f[1]=2;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<n;i++) b[i]=a[i+1]-a[i];
for(int i=1;i<n;i++) if(b[i]) c[++m]=b[i];
for(int i=1;i<(1<<m);i++) dp[i].fi=INF;
for(int i=1;i<(1<<m);i++){
int pos=32-__builtin_clz(i&(-i));
sum[i]=sum[i&(i-1)]+c[pos];
cnt[i]=cnt[i&(i-1)]+1;
}
for(register int i=0;i<(1<<m);i++){
register int rst=((1<<m)-1)^i;
for(register int j=rst;j;j=(j-1)&rst){
if(high(j)<high(i)) break;
(!sum[j])?upd(dp[i|j],dp[i],cnt[j]-1,g[cnt[j]]):
upd(dp[i|j],dp[i],cnt[j],f[cnt[j]]);
}
} printf("%d\n%d\n",dp[(1<<m)-1].fi,1ll*dp[(1<<m)-1].se*fac[dp[(1<<m)-1].fi]%MOD);
return 0;
}

洛谷 P7718 -「EZEC-10」Equalization(差分转化+状压 dp)的更多相关文章

  1. 2018.10.27 洛谷P2915奶牛混合起来Mixed Up Cows(状压dp)

    传送门 状压dp入门题. 按照题意建一个图. 要求的就是合法的链的总数. 直接f[i][j]f[i][j]f[i][j]表示当前状态为jjj,下一位要跟iii连起来的方案数. 然后从没被选并且跟iii ...

  2. 洛谷比赛 「EZEC」 Round 4

    洛谷比赛 「EZEC」 Round 4 T1 zrmpaul Loves Array 题目描述 小 Z 有一个下标从 \(1\) 开始并且长度为 \(n\) 的序列,初始时下标为 \(i\) 位置的数 ...

  3. [洛谷P3701]「伪模板」主席树

    题目大意:太暴力了,就不写了,看这儿 题解:对于每个$byx$的人,从源点向人连边,容量为此人的寿命. 对于每个手气君的人,从人向汇点连边,容量为此人的寿命. 对于每个$byx$的人与手气君的人,如果 ...

  4. LOJ 3119: 洛谷 P5400: 「CTS2019 | CTSC2019」随机立方体

    题目传送门:LOJ #3119. 题意简述: 题目说的很清楚了. 题解: 记恰好有 \(i\) 个极大的数的方案数为 \(\mathrm{cnt}[i]\),则答案为 \(\displaystyle\ ...

  5. LOJ 3120: 洛谷 P5401: 「CTS2019 | CTSC2019」珍珠

    题目传送门:LOJ #3120. 题意简述: 称一个长度为 \(n\),元素取值为 \([1,D]\) 的整数序列是合法的,当且仅当其中能够选出至少 \(m\) 对相同元素(不能重复选出元素). 问合 ...

  6. 「SCOI2005」互不侵犯 (状压DP)

    题目链接 在\(N\times N\) 的棋盘里面放 \(K\)个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共\(8\) 个格子 ...

  7. LOJ#6433. 「PKUSC2018」最大前缀和 状压dp

    原文链接https://www.cnblogs.com/zhouzhendong/p/LOJ6433.html 题解 枚举一个集合 S ,表示最大前缀和中包含的元素集为 S ,然后求出有多少个排列是这 ...

  8. loj2540 「PKUWC2018」随机算法 【状压dp】

    题目链接 loj2540 题解 有一个朴素三进制状压\(dp\),考虑当前点三种状态:没考虑过,被选入集合,被排除 就有了\(O(n3^{n})\)的转移 但这样不优,我们考虑优化状态 设\(f[i] ...

  9. 洛谷P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows 状压动归

    考场上空间开大了一倍就爆0了QAQ- Code: #include<cstdio> #include<algorithm> #include<cmath> usin ...

随机推荐

  1. Java中的函数式编程(三)lambda表达式

    写在前面 lambda表达式是一个匿名函数.在Java 8中,它和函数式接口一起,共同构建了函数式编程的框架.   lambda表达式乍看像是匿名内部类的一种语法糖,但实际上,它们是两种本质不同的事物 ...

  2. 初学Python-day13 文件处理1

    IO操作 一.os模块 作用:包含了操作系统的基本功能,提供了非常丰富的用来处理文件和目录的函数或方法. 1.属性 函数名 函数说明 name 获取操作系统的类型 uname 获取操作系统的信息(li ...

  3. 【UE4 设计模式】抽象工厂模式 Abstract Factory Pattern

    概述 描述 提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类:具体的工厂负责实现具体的产品实例 抽象工厂中每个工厂可以创建多种产品(如苹果公司生产iPhone.iPad): 工厂方法 ...

  4. LCP 07.传递消息

    题目 小朋友 A 在和 ta 的小伙伴们玩传信息游戏,游戏规则如下: 有 n 名玩家,所有玩家编号分别为 0 - n-1,其中小朋友 A 的编号为 0 每个玩家都有固定的若干个可传信息的其他玩家(也可 ...

  5. 反调试——11——检测TF标志寄存器

    反调试--11--检测TF标志寄存器 在intel的x86寄存器中有一种叫标志寄存器: 标志寄存器中的TF(Trap Flag)位,CPU在执行完一条指令后,如果检测到标志寄存器的TF位为1,则会产生 ...

  6. 6月8日 Scrum Meeting

    日期:2021年6月8日 会议主要内容概述: 确定6.9日下午两点到五点集中对接 初步确定主题配色和echarts默认图表颜色 一.进度情况 组员 负责 两日内已完成的工作 后两日计划完成的工作 工作 ...

  7. [软工作业]-软件案例分析-CSDN

    [软工作业]-软件案例分析-CSDN(app) 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 个人博客作业-软件案例分析 我在这个课程的目标是 ...

  8. 镜头Lens Image circle像圈的解释是什么意思

    Image circle镜头中指的是:像圈 像圈(image circle)是指入射光线通过镜头后,在焦平面上呈现出的圆形的明亮清晰的影像幅面,也称像面大小.镜头像圈由镜头光学结构决定,一旦设计完成, ...

  9. 摘录:ddr3内存条时序概念

    本文摘自:内存系列二:深入理解硬件原理 - 知乎 (zhihu.com),感谢作者! 上次虽然解决了小张的问题,却引发了他对内存原理的兴趣.这不他又来找我了,说我还欠他一个解释.这次我们约在一个咖啡馆 ...

  10. stop: Job failed while stopping start: Job is already running: networking eth0 not configured

    再给ubuntu系统重启网络服务的时候出现失败,"stop: Job failed while stopping start: Job is already running: network ...