传送门

首先涂区间,那么区间最多有 $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. Sublime Text 3中配置Python3的开发环境

    在Tools-->Build System-->New Build System 之后弹出如下界面: 将其内容修改为 代码: { "cmd": ["D:/so ...

  2. deep sort

    目录   1. 准备代码与数据 deep_sort开源代码 克隆到本地服务器 git clone https://github.com/nwojke/deep_sort.git 下载MOT16数据集( ...

  3. 预处理、const、static与sizeof-使用const与#define的特点及区别

    1:#define只是用来做文本替换的.例如: #define PI 3.1415926 float angle; angle=*PI/; 那么,程序进行编译的时候,编译器会首先将“#define P ...

  4. LC 241. Different Ways to Add Parentheses

    Given a string of numbers and operators, return all possible results from computing all the differen ...

  5. 深度学习之DCGAN

    1.知识点 """ DCGAN:相比GAN而言,使用了卷积网络替代全连接 卷积:256*256*3 --- > 28*28*14 -->结果 ,即H,W变小, ...

  6. 图片滚动js代码

          <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w ...

  7. Linux添加用户/权限/用户主目录等相关

    一. 用户主目录 useradd -d   ${path}   username -d命令是指定用户主目录, 添加完之后  su -  username 默认会转到 这个用户的主目录下,即 ${pat ...

  8. Linux高级命令 ==> find、grep、sed、awk

    一.find find命令用来在指定目录下查找文件.如果使用该命令时,不设置任何参数,则find命令将在当前目录下查找子目录与文件.并且将查找到的子目录和文件全部进行显示. 语法 find path ...

  9. Java泛型(2):泛型接口

    泛型不仅可以在类上实现,也可以在接口上实现.JDK中[Iterable<T> <-- Collection<E> <-- List<E>/Queue&l ...

  10. java数据结构之LinkedHashMap

    一.LinkedHashMap源码注释 public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map& ...