洛谷题面传送门

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

首先看到区间操作我们可以想到差分转换,将区间操作转化为差分序列上的一个或两个单点操作,具体来说我们设 \(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. TypeError: Restaurant() takes no arguments

    1. 错误描述 TypeError: Restaurant() takes no arguments 2. 原因:在编写__init__时,pycharm会自动添加关键字,有时会直接写称整型int, ...

  2. Unity——EasyTouch摇杆插件使用

    EasyTouch摇杆插件使用 Demo展示 双指缩放在电脑端无法掩饰,竖屏将就看看吧: 插件名叫EasyTouch,有需要给我留言,不想开仓库传了: 创建摇杆点这里: 初始化 On_Joystick ...

  3. UE4蓝图AI角色制作(七)之追逐玩家

    15.追逐玩家 现在我们的AI无法做出任何决策,它总是执行相同的决策.我们先把感知系统中的相关信息提供给AI,让AI知道如何做出决策,然后我们会修改行为树.我们首先需要创建新的黑板键,这样我们就能在行 ...

  4. JBOSS未授权访问漏洞利用

    1. 环境搭建 https://www.cnblogs.com/chengNo1/p/14297387.html 搭建好vulhub平台后 进入对应漏洞目录 cd vulhub/jboss/CVE-2 ...

  5. vue3.x相对于vue2.x生命周期改动

    vue3.x已经正式发布了,部分小伙伴已经用了vue3.x开发,部分小伙伴还在观望中,下面是两个影响比较大的改动 1.beforeDestroy和destroyed不能用了. 这个应该是vue2.x项 ...

  6. 极速上手 VUE 3 —— teleport传送门组件

    一.teleport 介绍 teleport 传送门组件,提供一种简洁的方式,可以指定它里面的内容的父元素.通俗易懂地讲,就是 teleport 中的内容允许我们控制在任意的DOM中,使用简单. 使用 ...

  7. Spring Cloud Gateway Route Predicate Factory 的使用

    Spring Cloud Gateway的使用 一.需求 二.基本组成 1.简介 2.核型概念 1.Route 路由 2.Predicate 谓语.断言 3.Filter 过滤器 3.工作原理 三.网 ...

  8. 在浏览器上开发GO和Vue!(基于code-server)

    在浏览器上开发GO和Vue!(基于code-server) 曾几何时,开发者们都被安装编程环境苦恼,尽管现在很多语言的开发环境已经不难装了,但是如果我们能有一个运行在云端的编译器,那么我们就可以随时随 ...

  9. 广域网(ppp协议、HDLC协议)

    文章转自:https://blog.csdn.net/weixin_43914604/article/details/105028759 学习课程:<2019王道考研计算机网络> 学习目的 ...

  10. Go并发编程--Mutex/RWMutex

    目录 一.前言 二. Mutex 2.1 案例 三. 实现原理 3.1 锁的实现模式 3.2 Go Mutex 实现原理 3.2.1 加锁 3.2.2 解锁 四. 源码分析 4.1 Mutex基本结构 ...