首先预处理出$f[i][j][k]$表示长度为$i$的序列,第一个位置是$j$,最后一个位置是$k$时合法的方案数。

从后往前枚举LCP以及那个位置应该改成什么。

用线段树维护区间内最左最右的已经确定的位置,以及区间内的合法方案数。

合并的时候只需要将左右儿子的答案乘起来,然后再乘以左儿子最右到右儿子最左这一段区间的方案数即可。

时间复杂度$O(n\log n)$。

#include<cstdio>
const int N=400010,M=1050000,P=1000000007;
int n,m,i,j,k,x,a[N],g[3][3],f[N][3][3],pos[N],v[N],l[M],r[M],val[M],ans=1;char ch[9],s[N];
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
inline void up(int&x,int y){x+=y;if(x>=P)x-=P;}
void build(int x,int a,int b){
l[x]=a,r[x]=b,val[x]=1;
if(a==b){pos[a]=x;return;}
int mid=(a+b)>>1;
build(x<<1,a,mid),build(x<<1|1,mid+1,b);
}
inline bool change(int x,int p){
if(~p){
if(x>1&&~v[x-1])if(g[v[x-1]][p])return 0;
if(x<n&&~v[x+1])if(g[p][v[x+1]])return 0;
}
v[x]=p,x=pos[x];
if(p<0)l[x]=r[x]=0;
for(x>>=1;x;x>>=1){
l[x]=l[x<<1]?l[x<<1]:l[x<<1|1];
r[x]=r[x<<1|1]?r[x<<1|1]:r[x<<1];
val[x]=1LL*val[x<<1]*val[x<<1|1]%P;
if(r[x<<1]&&l[x<<1|1])val[x]=1LL*val[x]*f[l[x<<1|1]-r[x<<1]+1][v[r[x<<1]]][v[l[x<<1|1]]]%P;
}
return 1;
}
inline int ask(){
int ret=val[1],t,i;
if(l[1]>1){
for(t=i=0;i<3;i++)up(t,f[l[1]][i][v[l[1]]]);
ret=1LL*ret*t%P;
}
if(r[1]<n){
for(t=i=0;i<3;i++)up(t,f[n-r[1]+1][v[r[1]]][i]);
ret=1LL*ret*t%P;
}
return ret;
}
int main(){
read(n);
for(i=1;i<=n;i++)read(a[i]);
read(m);
while(m--)scanf("%s",ch),g[ch[0]-'1'][ch[1]-'1']=1;
scanf("%s",s+1);
for(i=1;i<=n;i++)s[i]-='1',v[i]=s[i];
for(i=0;i<3;i++)f[1][i][i]=1;
for(i=1;i<n;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)if(f[i][j][k])for(x=0;x<3;x++)if(!g[k][x])up(f[i+1][j][x],f[i][j][k]);
build(1,1,n);
for(i=n;i;change(a[i--],-1))for(j=0;j<s[a[i]];j++)if(change(a[i],j))up(ans,ask());
return printf("%d",ans),0;
}

  

BZOJ3019 : [Balkan2012]handsome的更多相关文章

  1. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  2. [swustoj 443] Handsome Swap

    Handsome Swap(0443) Time limit(ms): 1000 Memory limit(kb): 65535 Submission: 89 Accepted: 20 Accepte ...

  3. BZOJ3024 : [Balkan2012]balls

    问题1: ans=max(sum[n]-(sum[i]-sum[j-1])+a[i]*(i-j+1)) =max(sum[n]-sum[i]+sum[j-1]+a[i]*(i+1)-a[i]*j) = ...

  4. 【BZOJ】3022: [Balkan2012]The Best Teams

    原题链接 题面 (为啥这题没有题面-- 给出\(N\)个人,和年龄\(age_{i},skill_{i}\) 然后给出\(M\)个询问,就是年龄在\(a\)以下选不超过\(k\)个人 要求选择的人水平 ...

  5. BZOJ3022 : [Balkan2012]The Best Teams

    将选手和询问按照年龄排序,即可去掉年龄的限制. 将所有选手按水平排序后维护线段树,显然最优解一定是从大到小贪心选择. 线段树上每个节点维护: $g[0/1]:r+1$不选/选的时候,$l$选不选. $ ...

  6. BZOJ 3022 [Balkan2012]The Best Teams(扫描线+线段树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3022 [题目大意] 给定n个球员,第i个球员年龄为AGEi,水平为SKILLi. 没有 ...

  7. Javascript实用方法二

    承接上一篇, Object keys object的keys方法能够获取一个给定对象的所有键(key/属性名)并以数组的形式返回.这个方法可以用于键的筛选.匹配等. var basket = { st ...

  8. 【NLP】Python NLTK获取文本语料和词汇资源

    Python NLTK 获取文本语料和词汇资源 作者:白宁超 2016年11月7日13:15:24 摘要:NLTK是由宾夕法尼亚大学计算机和信息科学使用python语言实现的一种自然语言工具包,其收集 ...

  9. 跟着老男孩教育学Python开发【第五篇】:模块

    递归的案例:阶乘 1*2*3*4*5*6*7- def func(num):     if num == 1:         return 1     return num * func(num - ...

随机推荐

  1. mongodb数据库安装及常见操作

    客户端和服务端的安装 # rpm -ivh mongo-10gen-2.4.6-mongodb_1.x86_64.rpm mongo-10gen-server-2.4.6-mongodb_1.x86_ ...

  2. 解决报错error the @annotation pointcut expression is only supported at Java 5

    eclipse搭建环境后报错 error the @annotation pointcut expression is only supported at Java 5 错误意思大致是:注释切入点表达 ...

  3. Intellij IDEA14 搜索框及控制台乱码解决

    搜索ctrl+F及ctrl+H的搜索框.调试的时候控制台.导入module都显示为为中文乱码 如下: 解决方案: File->Setting->IDE Settings->Appea ...

  4. 使用 CSS overscroll-behavior 控制滚动行为:自定义下拉刷新和溢出效果

    CSS 的新属性 overscroll-behavior 允许开发者覆盖默认的浏览器滚动行为,一般用在滚动到顶部或者底部. 背景 滚动边界和滚动链接(boundary & chaining) ...

  5. 玩树莓派(raspberry pi) 2/3 raspbian的遇到的一些问题

    raspberry pi买回来玩了一段时间,现在就记录一下入门遇到的一些问题吧. 首先是烧写镜像,和安装电脑系统是一样的道理. 先要有一个制作一个U启动盘.先将SD卡格式化,再用Win32DiskIm ...

  6. STM32学习及应用笔记二:一次运算符优先级造成的错误

    本人在最近一个项目的开发中,出现一个应为疏忽运算符优先级造成的问题,检查了很久才发现问题,所以觉得运算符的优先级问题还是有必要再研究一下.具体的问题是这样的,我采集了传感器的原始数据,然后会对数据进行 ...

  7. 前端工程化-webpack-cli(官方开发中。。。)

  8. mysql操作查询结果case when then用法举例

    举例1: 使用该查询,得出iFavoriteID,iFavUserType ,cUser,iArticleID,dFavoriteTime五个字段的值: SELECT iFavoriteID,CASE ...

  9. python使用ssdb的队列,用于替换canal+rabbitmq

    # pip install -i https://mirrors.aliyun.com/pypi/simple/ pyssdb import pyssdb c = pyssdb.Client('172 ...

  10. [转] 基于NodeJS的前后端分离的思考与实践(五)多终端适配

    前言 近年来各站点基于 Web 的多终端适配进行得如火如荼,行业间也发展出依赖各种技术的解决方案.有如基于浏览器原生 CSS3 Media Query 的响应式设计.基于云端智能重排的「云适配」方案等 ...