传送门

首先涂区间,那么区间最多有 $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. UITableView动态改变Cell高度

    demo下载地址:https://github.com/smileyborg/TableViewCellWithAutoLayout 版权声明:本文为博主原创文章,未经博主允许不得转载.

  2. L1-049 天梯赛座位分配 (20 分)

    L1-049 天梯赛座位分配 (20 分)(Java解法) 天梯赛每年有大量参赛队员,要保证同一所学校的所有队员都不能相邻,分配座位就成为一件比较麻烦的事情.为此我们制定如下策略:假设某赛场有 N 所 ...

  3. 尚硅谷周阳老师-redis脑图课件

    因为脑图原件是.mmap格式,使用wps和xmind打开都会有格式不兼容的问题,这里我们可以使用mindmanager存为html5交互式格式, 提供在线阅读.因为阿里云学生服务器带宽有限,这里打开加 ...

  4. Kafka 概述

    Kafka 是一个分布式的基于发布/订阅模式的消息队列(Message Queue),主要应用于大数据实时处理领域. Kafka 中,客户端和服务器之间的通信是通过 TCP 协议完成的. 一.传统消息 ...

  5. PHP 二维数组去重方法

    php二维数组的去重策略,如果需要根据某字段去重(其他字段可能不一致),那么需要使用循环策略,如果去重的都是相同的(字段,值),那么可以用序列化方式. $allComments = array_map ...

  6. Mac系统下,docker安装nextcloud,打造个人本地网盘

    1.安装docker 推荐下载地址:http://get.daocloud.io/#install-docker-for-mac-windows   2.拉取镜像 $ docker pull next ...

  7. [jquery]JSON.parse()与JSON.stringify()

    JSON.parse()[从一个字符串中解析出json对象] 例子: //定义一个字符串 var data='{"name":"goatling"}' //解析 ...

  8. hive基础指令

  9. Windows10系统python环境下安装Dlib库(转载,蔡军帅亲测可用)

    Dlib是一个很优秀的机器学习库,最近做人脸识别要用到这个库,简要记录一下配置过程,准备工作: 1.python环境 2.安装好pip(这里有个简单的安装教程) 3.Dlib包,贴一个我安装的版本,链 ...

  10. Linux命令集锦:chmod命令

    chmod命令是用来变更文件或目录的权限. 权限范围的表示法如下: u:User,即文件或目录的拥有者: g:Group,即文件或目录的所属群组: o:Other,除了文件或目录拥有者或所属群组之外, ...