考虑容斥,枚举哪些串必然出现,那么贡献为$(-1)^{选中的串数}$。

设$f[i][j]$表示$i$的子树内,$i$点往上是$j$这个串的贡献之和,那么总状态数为$O(n+m)$,用map存储$f$。

将子树的DP值与父亲合并时,按串长分类讨论:

若子树串比较长,那么暴力枚举它的前缀状态转移即可。

若父亲串比较长,那么一个子树状态对父亲状态的贡献编码后对应一个区间。

扫描线处理区间,对于相邻的区间内的所有DP值整体乘上一个数,线段树维护。

最后沿着线段树上有效节点走,即可不重不漏地得到所有新的状态。

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

#include<cstdio>
#include<map>
#include<algorithm>
using namespace std;
typedef map<int,int>T;
const int N=20010,M=860000,MAXN=2100000,U=300010,P=1234567;
int n,m,i,j,x,y,g[N],nxt[N],sub[M],right[M],ans;char ch[9];
T f[N];T::iterator k;int tmp[U],tag[MAXN];bool s[MAXN];
struct E{int x,y;E(){}E(int _x,int _y){x=_x,y=_y;}}q[U],e[U*2];
inline bool cmp(const E&a,const E&b){return a.x<b.x;}
inline void up(int&a,int b){a=a+b<P?a+b:a+b-P;}
inline void tag1(int x,int p){tag[x]=1LL*tag[x]*p%P;}
inline void pb(int x){if(tag[x]!=1)tag1(x<<1,tag[x]),tag1(x<<1|1,tag[x]),tag[x]=1;}
void build(int x,int a,int b){
if(a==b)return;
tag[x]=1;
int mid=(a+b)>>1;
build(x<<1,a,mid),build(x<<1|1,mid+1,b);
}
void ins(int x,int a,int b,int c,int p){
if(a==b){
up(tag[x],p);
s[x]=!!tag[x];
return;
}
pb(x);
int mid=(a+b)>>1;
if(c<=mid)ins(x<<1,a,mid,c,p);else ins(x<<1|1,mid+1,b,c,p);
s[x]=s[x<<1]|s[x<<1|1];
}
void change(int x,int a,int b,int c,int d,int p){
if(c<=a&&b<=d){tag1(x,p);return;}
pb(x);
int mid=(a+b)>>1;
if(c<=mid)change(x<<1,a,mid,c,d,p);
if(d>mid)change(x<<1|1,mid+1,b,c,d,p);
}
int ask(int x,int a,int b,int c){
if(a==b)return tag[x];
pb(x);
int mid=(a+b)>>1;
return c<=mid?ask(x<<1,a,mid,c):ask(x<<1|1,mid+1,b,c);
}
void dfs(int x,int a,int b,T&f){
if(!s[x])return;
if(a==b){
if(tag[x])up(f[a<<4&1048575],tag[x]);
tag[x]=s[x]=0;
return;
}
pb(x);
int mid=(a+b)>>1;
dfs(x<<1,a,mid,f),dfs(x<<1|1,mid+1,b,f);
s[x]=0;
}
inline void solve(){
int i,j,cnt=0,s=0;
for(i=0;i<m;i++){
tmp[i]=0;
for(j=sub[q[i].x];~j;j=sub[j])up(tmp[i],ask(1,0,M,j));
e[++cnt]=E(q[i].x,q[i].y);
e[++cnt]=E(right[q[i].x],P-q[i].y);
}
sort(e+1,e+cnt+1,cmp);
for(i=1;i<=cnt;i++){
if(i>1&&e[i].x>e[i-1].x)change(1,0,M,e[i-1].x,e[i].x-1,s);
up(s,e[i].y);
}
for(i=0;i<m;i++)if(tmp[i])ins(1,0,M,q[i].x,1LL*q[i].y*tmp[i]%P);
}
int main(){
scanf("%d%d",&n,&m);
for(i=2;i<=n;i++)scanf("%d",&x),nxt[i]=g[++x],g[x]=i;
while(m--){
scanf("%d%s",&x,ch);
for(y=j=0;j<5;j++)y=y<<4|(ch[j]-'0'+1);
f[x+1][y]=P-1;
}
for(sub[0]=-1,right[0]=M,i=1;i<M;i++)for(j=0;;j++)if(i>>(j*4)&15){
sub[i]=i-(((i>>(j*4))&15)<<(j*4));
right[i]=i+(1<<(j*4));
break;
}
build(1,0,M);
for(i=n;i;i--){
for(j=1;j<=10;j++)f[i][j<<16]=1;
for(k=f[i].begin();k!=f[i].end();k++)ins(1,0,M,k->first,k->second);
for(j=g[i];j;j=nxt[j]){
m=0;
for(k=f[j].begin();k!=f[j].end();k++)q[m++]=E(k->first,k->second);
solve();
}
f[i].clear();
dfs(1,0,M,f[i]);
}
for(ans=i=1;i<=n;i++)ans=ans*10%P;
up(ans,P-f[1][0]);
return printf("%d",ans),0;
}

  

BZOJ3537 : [Usaco2014 Open]Code Breaking的更多相关文章

  1. bzoj AC倒序

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

  2. 【Coursera】Security Introduction -Eighth Week(1)

    Security Introduction People With Bad Intent 今天,Bob 向 Alice 发送了一条 "Hello,Allice!" 的信息,他们希望 ...

  3. Coursera:Internet History ,Techornology and Security

    WEEK1 War Time Computing and Communication Bletchley Park 布莱彻利庄园:a top-secret code breaking effort b ...

  4. Internet History, Technology, and Security(week1)——History: Dawn of Electronic Computing

    前言: 第一次进行课程学习,在反复观看视频和查找字典翻译理解后选出了视频中个人认为较重要的概念,以下并不按照逐句翻译,中文概括大意余下自由发挥,对老师想要告诉我们的历史有一个初步的了解,顺便锻炼以下英 ...

  5. [BZOJ3449] [Usaco2014 Feb]Secret Code

    Description Farmer John has secret message that he wants to hide from his cows; the message is a str ...

  6. How can I protect derived classes from breaking when I change the internal parts of the base class?

    How can I protect derived classes from breaking when I change the internal parts of the base class? ...

  7. 5 Tips for creating good code every day; or how to become a good software developer

    Being a good developer is like being any other good professional, it’s all it’s about doing as much ...

  8. POJ 3904 Sky Code (容斥原理)

    B - Sky Code Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit ...

  9. POJ Sky Code 莫比乌斯反演

    N. Sky Code Time Limit: 1000ms Case Time Limit: 1000ms Memory Limit: 65536KB   64-bit integer IO for ...

随机推荐

  1. json如果不在pom中添加依赖会抛出500异常

    所以必须添加以下依赖: <!--jackson相关依赖--><!-- https://mvnrepository.com/artifact/com.fasterxml.jackson ...

  2. python目录和文件的列表清单

    import os # 通过给定的文件夹,列举出这个文件夹当中,所有的文件,以及文件夹,子文件夹当中的所有文件def listFilesToTxt(dir,file): # 1.列举出,当前给定的文件 ...

  3. CAS统一登录认证好文汇集贴

    悟空的专栏 https://blog.csdn.net/u010475041/article/category/7156505 LinBSoft的专栏 https://blog.csdn.net/ol ...

  4. Caused by: java.lang.ClassNotFoundException: backtype.storm.topology.IRichSpout

    1:初次运行Strom程序出现如下所示的错误,贴一下,方便脑补,也希望帮助到看到的小伙伴: 错误如下所示,主要问题是刚开始使用maven获取jar包的时候需要写<scope>provide ...

  5. RSA javascript加密 lua解密

    一个在线RSA非对称加密解密,可以用这个地址生成公钥和私钥 https://blog.zhengxianjun.com/online-tool/rsa/ javascript加密 jsencrypt. ...

  6. alpha冲刺3/10

    目录 摘要 团队部分 个人部分 摘要 队名:小白吃 组长博客:hjj 作业博客:冲刺3 团队部分 后敬甲(组长) 过去两天完成了哪些任务 文字描述 组织第一次团队编程 继续阅读小程序开发文档 接下来的 ...

  7. Linux 命令行敲命令 光标移动快捷键

    在单词之间跳转,使用Ctrl+左右键. Ctrl+a跳到本行的行首, Ctrl+e则跳到页尾. Ctrl+u删除当前光标前面的文字 ctrl+k-删除当前光标后面的文字 Ctrl+w和Alt+d-对于 ...

  8. machinekey生成工具 v1.0 官方最新版

    http://www.33lc.com/soft/66056.html 电信下载 广东电信下载 厦门电信下载 湖北电信下载 江苏电信下载 网通下载 陕西网通下载 山东网通下载 甘肃网通下载 山西网通下 ...

  9. python全栈开发day99-DRF序列化组件

    1.解释器组件源码分析 https://www.processon.com/view/link/5ba0a8e7e4b0534c9be0c968 2.基于CBV的接口设计 1).django循环que ...

  10. 054 kafka内部机制

    一:数据格式与数据存储 1.总结 存储在磁盘文件中(index+log) 顺序读写的 基于offset偏移量来管理数据的(主要是读操作) 由分区器根据key值决定数据分布到哪个分区,默认使用hash ...