传送门

首先涂区间,那么区间最多有 $2n$ 个相邻位置不同的情况,并且连续相同的颜色可以合并起来

那么这样操作完以后,区间长度最多为 $2n$

发现涂完一段区间以后其他的操作都不能出现一边在区间内而另一边在区间外的情况

又因为区间长度 $n<=1000$ ,时间 $6$ 秒,考虑一下不满的 $n^3$ 的区间 $dp$

设 $f[i][j]$ 表示把区间 $[i,j]$ 涂成最终状态的方案数

设 $mi[i][j]$ 表示区间 $[i,j]$ 内最小的颜色编号,$L[i]$ 表示颜色 $i$ 最左边的位置,$R[i]$ 表示颜色 $i$ 最右边的位置

设 $p=mi[i][j]$

那么枚举最小的颜色涂的区间为 $[l,r]$,显然 $l<=L[p],r>=R[p]$,发现 $l,r$ 把区间 $i,j$ 分成了 $4$ 个部分:$[i,l-1],[l,L[p]-1],[R[p]+1,r],[r,j]$

哦,对了,还有 $[L[p],R[p]]$ 中间的几个部分,中间这一段被颜色 $p$ 分成了很多块,每一块内部也是独立的,设中间这些块的方案数为 $sum$

有 $f[i][j]=\sum_{l=i}^{L[p]}\sum_{r=R[p]}^{j}f[i][l-1]f[l][L[p]-1]f[R[p]+1][r]f[r+1][j] \cdot sum$

然后因为 $l,r$ 是独立的,所以分别计算即可做到 $n^3$ ,求 $sum$ 也只要预处理一下 $nxt[i]$ 表示位置 $i$ 下一个同颜色的位置即可

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=,M=2e6+,mo=;
inline int fk(int x) { return x>=mo ? x-mo : x; }
int n,m,a[M],b[M],tot;
int L[N],R[N],mi[N][N],f[N][N];
int pre[N],nxt[N];
int main()
{
n=read(),m=read();
for(int i=;i<=m;i++) a[i]=read();
for(int i=;i<=m;i++) if(a[i]!=a[i-]) b[++tot]=a[i];
if(tot>n*) { printf("0\n"); return ; }
m=tot; for(int i=;i<=m;i++) a[i]=b[i];
for(int i=;i<=m;i++)
{
if(pre[a[i]]) nxt[ pre[a[i]] ]=i;
pre[a[i]]=i;
}
for(int i=;i<=n;i++) nxt[ pre[a[i]] ]=m+;
memset(L,0x3f,sizeof(L)); memset(mi,0x3f,sizeof(mi));
for(int i=;i<=m;i++) L[a[i]]=min(L[a[i]],i),R[a[i]]=max(R[a[i]],i);
for(int i=;i<=m;i++)
for(int j=i;j<=m;j++)
for(int k=i;k<=j;k++)
mi[i][j]=min(mi[i][j],a[k]);
for(int i=;i<=m+;i++)
{
if( i>=&&i<=m && L[mi[i][i]]==i && R[mi[i][i]]==i )
f[i][i]=;
for(int j=i+;j<=m+;j++) f[j][i]=;
for(int j=;j<=i-;j++) f[i][j]=;
}
for(int k=;k<m;k++)
for(int i=;i+k<=m;i++)
{
int p=mi[i][i+k]; if(p>N) continue;
if(L[p]<i||R[p]>i+k) continue;
int cntl=,cntr=,t=;
for(int j=i;j<=L[p];j++)
cntl=fk(cntl+1ll*f[i][j-]*f[j][L[p]-]%mo);
for(int j=R[p];j<=i+k;j++)
cntr=fk(cntr+1ll*f[R[p]+][j]*f[j+][i+k]%mo);
for(int j=L[p];j<R[p];j=nxt[j])
t=1ll*t*f[j+][nxt[j]-]%mo;
f[i][i+k]=1ll*cntl*cntr%mo*t%mo;
// cout<<i<<" "<<i+k<<" "<<f[i][i+k]<<endl;
}
printf("%d\n",f[][m]);
return ;
}

Codeforces 1178F2. Long Colorful Strip的更多相关文章

  1. Codeforces 909 D. Colorful Points (模拟)

    题目链接: Colorful Points 题意: 给出一段字符串(长度最大为1e6),每次操作可以删除字符串中所有相邻字符与其不同的字符.例如:aabcaa 删除一次就变成了aa,就无法再删除了.题 ...

  2. 【Codeforces 246D】Colorful Graph

    [链接] 我是链接,点我呀:) [题意] 让你找到所有和x颜色的点中,和该颜色的点颜色不同的相邻的点的个数(重复颜色算一次) 求出哪种颜色的所要求的点的数量最多. [题解] 对于每一条边只会被查到两次 ...

  3. CF1178 F1 Short Colorful Strip

    题目链接 题意 有个长度为\(m\)公分的布,要在上面每公分都染上颜色,整块布染恰好\(n(n=m)\)种颜色.颜色标号从\(1\)到\(n\).染色需遵循: 1.从颜色\(1\)到颜色\(n\)依次 ...

  4. CF1178F Short/Long Colorful Strip(DP)

    说起来,这题好像也不难-- 先考虑 F1 怎么做. 既然别的方法都不行不如试试\(f_{i,j}\) 表示在刚刚准备开始涂 \([i,j]\) 中最小编号的颜色之前,整个区间是同色的,且最后能做到 \ ...

  5. Codeforces Global Round 4

    目录 Contest Info Solutions A. Prime Minister B. WOW Factor C. Tiles D. Prime Graph E. Archaeology F1. ...

  6. CodeForces 505B Mr. Kitayuta's Colorful Graph

    Mr. Kitayuta's Colorful Graph Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d ...

  7. Codeforces Round #278 (Div. 1) B. Strip multiset维护DP

    B. Strip Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/487/problem/B De ...

  8. Codeforces Round #286 (Div. 1) D. Mr. Kitayuta's Colorful Graph 并查集

    D. Mr. Kitayuta's Colorful Graph Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/ ...

  9. DFS/并查集 Codeforces Round #286 (Div. 2) B - Mr. Kitayuta's Colorful Graph

    题目传送门 /* 题意:两点之间有不同颜色的线连通,问两点间单一颜色连通的路径有几条 DFS:暴力每个颜色,以u走到v为结束标志,累加条数 注意:无向图 */ #include <cstdio& ...

随机推荐

  1. Elasticsearch学习笔记-Delete By Query API

    记录关于Elasticsearch的文档删除API的学习 首先官网上Document APIs介绍了 Delete API 和Delete By Query API. Delete API可以通过指定 ...

  2. linux环境中关闭tomcat,通过shutdown.sh无法彻底关闭--线程池

    最近测试环境上测试的项目通过shutdown.sh始终无法彻底关闭. 之前临时解决方法两种: 第一:通过ps -ef|grep tomcat查看到tomcat的进程直接使用kill来杀死进程. 第二: ...

  3. Linux设备驱动程序 之 原子操作

    原子整数操作 当共享资源是一个简单的整数值时,可以使用内核提供的一种原子的整数类型,称为atomic_t,定义在<linux/types.h>中,操作定义在<linux/atomic ...

  4. php屏蔽电话号码中间四位

    php屏蔽电话号码中间四位 一.总结 一句话总结: 直接就是substr_replace函数:$str = substr_replace("13966778888",'****', ...

  5. selenium 右侧滚动条操作

    对于web上有右侧滚动条的操作 可用使用JS语句执行 拖到底部 js = "var q=document.documentElement.scrollTop=10000"brows ...

  6. 性能分析 | JVM发生内存溢出的8种原因及解决办法

    推荐阅读:史上最详细JVM与性能优化知识点综合整理 1.Java 堆空间 2.GC 开销超过限制 3.请求的数组大小超过虚拟机限制 4.Perm gen 空间 5.Metaspace 6.无法新建本机 ...

  7. 如何将ubuntu16.04升级到ubuntu 18.04?

    答:步骤如下: 1. sudo apt update (更新软件源) 2. sudo apt upgrade (更新内核相关的包) 3. sudo apt dist-upgrade 4.  sudo ...

  8. LC 979. Distribute Coins in Binary Tree

    Given the root of a binary tree with N nodes, each node in the tree has node.val coins, and there ar ...

  9. 机器学习 - 案例 - 样本不均衡数据分析 - 信用卡诈骗 ( 标准化处理, 数据不均处理, 交叉验证, 评估, Recall值, 混淆矩阵, 阈值 )

    案例背景 银行评判用户的信用考量规避信用卡诈骗 ▒ 数据 数据共有 31 个特征, 为了安全起见数据已经向了模糊化处理无法读出真实信息目标 其中数据中的 class 特征标识为是否正常用户 (0 代表 ...

  10. CACTI批量添加linux主机sh脚本

    关于批量添加就三个文件:add_hosts.sh,ips.txt,thold_test.php,关于如何使用,更是简单 ./add_hosts.sh --add #执行批量工作./add_hosts. ...