(题干中的废话已经划去)

dp显而易见

收益为负数的可以直接扔掉不管。不要一定更优

子串问题,考虑SAM

建立广义SAM

尝试匹配,匹配到的位置的parent树祖先如果有完整的串,那么可以从这个串转移

考虑祖先不好考虑

不妨考虑i对j(i<j)的贡献,就是子树了

线段树维护dfn序,区间对val取max

SAM学傻了

这个,由于是"完整出现”,所以AC自动机就可以(比广义SAM好写好调)

走一走属于第j个串的路径,对应的fail树的祖先包含i(i<j)的结束位置,那么可以转移

所以,同理,走完i之后,整个fail树子树的dp值和val取max

但是注意一点,根节点标号是0(反正我trie都这样写)

代码:

#include<bits/stdc++.h>
#define il inline
#define int long long
#define reg register int
#define mid ((l+r)>>1)
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){char ch;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x);
}
namespace Miracle{
const int N=300000+5;
int n,m;
struct node{int nxt,to;
}e[2*N];
int hd[N],cnt;
void add(int x,int y){e[++cnt].nxt=hd[x];e[cnt].to=y;hd[x]=cnt;
}
char s[N],b[N];
int len[N],st[N];
ll v[N],f[N];
int dfn[N],dfn2[N];
int df;
struct seg{ll mx;ll tag;
}t[4*N];
void pushup(int x){t[x].mx=max(t[x<<1].mx,t[x<<1|1].mx);
}
void pushdown(int x){if(t[x].tag<=0) return;t[x<<1].tag=max(t[x<<1].tag,t[x].tag);t[x<<1].mx=max(t[x<<1].mx,t[x].tag);t[x<<1|1].tag=max(t[x<<1|1].tag,t[x].tag);t[x<<1|1].mx=max(t[x<<1|1].mx,t[x].tag);t[x].tag=0;
}
void upda(int x,int l,int r,int L,int R,ll c){if(L<=l&&r<=R){t[x].mx=max(t[x].mx,c);t[x].tag=max(t[x].tag,c);return ;}pushdown(x);if(L<=mid) upda(x<<1,l,mid,L,R,c);if(mid<R) upda(x<<1|1,mid+1,r,L,R,c);pushup(x);
}
ll query(int x,int l,int r,int p){if(l==r){return t[x].mx;}pushdown(x);if(p<=mid) return query(x<<1,l,mid,p);else return query(x<<1|1,mid+1,r,p);
}
void cle(int x,int l,int r){t[x].mx=0;t[x].tag=0;if(l==r) return;cle(x<<1,l,mid);cle(x<<1|1,mid+1,r);
}
struct AC{int fail[N],ch[N][26];int cnt;void ins(char *s,int l){//int len=strlen(s+1);int now=0;for(reg i=1;i<=l;++i){int c=s[i]-'a';if(!ch[now][c]) ch[now][c]=++cnt;now=ch[now][c];}}void build(){queue<int>q;for(reg i=0;i<26;++i){if(ch[0][i]) fail[ch[0][i]]=0,q.push(ch[0][i]);}while(!q.empty()){int x=q.front();q.pop();for(reg i=0;i<26;++i){if(ch[x][i]){fail[ch[x][i]]=ch[fail[x]][i];q.push(ch[x][i]);}else ch[x][i]=ch[fail[x]][i];}}for(reg i=1;i<=cnt;++i){add(fail[i],i);}}void clear(){memset(fail,0,sizeof fail);cnt=0;memset(ch,0,sizeof ch);}void dfs(int x){dfn[x]=++df;for(reg i=hd[x];i;i=e[i].nxt){int y=e[i].to;dfs(y);}dfn2[x]=df;}ll wrk(char *s,int l,int id){ll ret=0;int now=0;for(reg i=1;i<=l;++i){int c=s[i]-'a';now=ch[now][c];//        cout<<"now "<<now<<" i "<<i<<" dfn "<<dfn[now]<<endl;ret=max(ret,query(1,1,df,dfn[now]));}//    cout<<dfn[now]<<".. "<<dfn2[now]<<endl;upda(1,1,df,dfn[now],dfn2[now],ret+v[id]);return ret;}
}ac;
void clear(){ac.clear();if(df)cle(1,1,df);df=0;cnt=0;n=0;memset(hd,0,sizeof hd);}
int main(){//return 0;int t;rd(t);while(t--){clear();    rd(m);int tot=0;    for(reg i=1;i<=m;++i){scanf("%s",b+1);scanf("%lld",&v[i]);st[i]=tot+1;len[i]=strlen(b+1);for(reg j=tot+1;j<=tot+len[i];++j){s[j]=b[j-tot];}    tot=tot+len[i];ac.ins(b,len[i]);}//    cout<<" after ac.ins "<<endl;
        ac.build();ac.dfs(0);//find dfnll ans=0;//    cout<<" let's wrk "<<endl;for(reg i=1;i<=m;++i){//        cout<<" ii "<<i<<"--------------------"<<v[i]<<" len "<<len[i]<<" st "<<st[i]<<endl;//if(v[i]<=0) continue;for(reg j=st[i];j<=st[i]+len[i]-1;++j){b[j-st[i]+1]=s[j];}//    cout<<b+1<<endl;f[i]=ac.wrk(b,len[i],i)+v[i];//    cout<<i<<" : "<<f[i]<<endl;ans=max(ans,f[i]);}printf("%lld\n",ans);}return 0;
}}
signed main(){freopen("2963.in","r",stdin);freopen("2963.out","w",stdout);Miracle::main();return 0;
}/*Author: *Miracle*Date: 2019/2/3 11:36:24
*/

转载于:https://www.cnblogs.com/Miracevin/p/10350805.html

fzyjojP2963 -- [校内训练20161227]疫情控制问题相关推荐

  1. 校内训练赛题解第三篇

    校内训练赛题解 人气估值 解题思路 脑力训练计划 (模拟 + 字符串) 解题思路 大暑赛期(贪心 + 思维) 人气估值 题目描述 你是某动画制作公司的企划部长.如今动画制作公司制作的东西,已经不仅仅局 ...

  2. 疫情控制住了,公司却倒闭了!

    1 2020年3月15日,深圳北站.我拖着行李箱准备离开这座曾经打拼了5年的城市,进候车厅的那刻我重新打量了一下这个仍旧朝气蓬勃的城市. 望着雕刻在石头上的那句"来了就是深圳人". ...

  3. 国家返工潮?国外放假潮?疫情控制我们狠狠秀了一次“肌肉”

    此前世界卫生组织(WHO)宣布新冠病毒爆发为全球大流行病,世界范围内共有超过4291人因此丧生,至少119470人感染. 国外科技公司的应对措施 众多科技公司选择无限期的延长员工在家办公时间,这是为了 ...

  4. 19_05_01校内训练[划分]

    题意 给出长度为n的序列,只有1,0,-1.要求将其划分为若干长度在[L,R]之间的连续序列,一个序列若和大于0,造成1的贡献:若小于0,造成-1的贡献:否则没有贡献.求最大的贡献. 时间复杂度要求n ...

  5. fzyzojP3372 -- [校内训练20171124]博弈问题

    对于每个点都要答案 还是异或 trie树合并石锤了 朴素枚举是O(n^2*17)的 怎么办呢? 我们发现合并的时候,一些部分的trie的子树还是不变的 改变的部分也就是合并的复杂度可以接受 鉴于大部分 ...

  6. 20170910校内训练

    CCT 最近学校又发了n本五三题霸,BBS看到后十分高兴.但是,当他把五三拿到手后才发现,他已经刷过这些书了!他又认真地看了一会儿,发现新发的这些五三是2017版的,而他刷的是2016版的.现在他想找 ...

  7. 20170908校内训练

    题意: 学过博弈论的同学都知道Nim游戏后手必胜的条件是异或和为0 给定一棵树 ,支持修改单点点权,询问链上异或和 预处理每个点到根的路径的异或和 由于异或的特殊性质,在求链x->y的异或和的时 ...

  8. 19_03_26校内训练[魔法卡片]

    题意 有n张有序的卡片,每张卡片上恰有[1,m]中的每一个数,数字写在正面或反面.每次询问区间[l,r],你可以将卡片上下颠倒,问区间中数字在卡片上方的并的平方和最大是多少.q,n*m≤1,000,0 ...

  9. NOIP2012:疫情控制(二分、贪心、树上倍增)

    解析 二分的单调性较为明显,一路推导下去的性质都不算太难想,正解的思路还是不难想到的 但从头到尾都实现很考验思维的严密性和代码能力 然后我就双重被考验挂了qwq 第一交的时候一个地方把倍增的dis数组 ...

最新文章

  1. iOS -- iOS11新特性,如何适配iOS11
  2. 由于代码已经过优化或者本机框架位于调用堆栈之上,无法计算表达式的值 解决方案...
  3. 华东交通大学计算机调剂,华东交通大学2018考研调剂信息
  4. Python中numpy库unique函数解析
  5. Window核心编程
  6. .NET实现之(WebService数据提供程序)
  7. @AspectJ中的切点表达式详解
  8. php 数组重新打乱_PHP 将数组打乱 shuffle 函数
  9. Bash Shell 注释多行的几种方法(转)
  10. Eclipse 导入外部jar包
  11. 如何在Ubuntu系统中使用github
  12. 要知其然还要知其所以然printChar
  13. 主题:讲解三层代码讲解--第三课(*****) DATE:2004-05-28
  14. RedHat6.6安装thefuck工具,自动纠正错误命令
  15. DOM事件+正则表达式
  16. 关于语言发育迟缓的孩子
  17. css实现立体感按钮
  18. 视频号新人直播应该准备什么?
  19. vue3运行npm run serve无反应,选择跳转后会自动跳入文件路径中
  20. Fortran编译初步

热门文章

  1. HeadFir st 设计模式学习笔记8--模板方法模式
  2. easyui edatagrid saveRow保存刷新
  3. C#WinForm开发笔记——基本控件(二)
  4. PoseiSwap IDO在Bounce上启动在即,如何参与
  5. Archlinux命令之软件卸载
  6. android传感器灵敏度,Android-Sensor重力感应器灵敏度问题
  7. Docker安装mongo数据库,navicat联接操作mongo
  8. 常用数据类型打印格式
  9. 2021-2027全球与中国金属粉末成型3D打印机市场现状及未来发展趋势
  10. 微信小程序使用for循环遍历对象