被安排的明明白白,一个调了四小时多的题目,最后发现区间更新不会,还把所有数据结构交给我,EXM???喵喵喵。今天七夕可以说是很惨了,I'm still loving you my dear "father" even if it can not be.
#include<cstdio>
#include<iostream>
#include<bitset>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#define mp make_pair
#define pb push_back
#define ll long long
#define lc no[x].ch[0]
#define rc no[x].ch[1]
#define pa no[x].fa
#define db double
#define ls x<<1
#define rs x<<1|1
#define For(i,a,b) for(int i=a;i<=b;i++)
#define Forr(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int maxn=300010;
const int maxt=20010;
int n,m;
char str[maxn];
int ch[maxn][27],fail[maxn],fa[maxn],dfsn[maxn],ln[maxn],q[maxn],cc[maxt],opo[maxn],pos[maxn];
int fir[maxn],v[maxn*2],nxt[maxn*2];
int cnt,root,M,ts,pv;
int h,t;
void add_e(int a,int b)
{
++M;nxt[M]=fir[a];fir[a]=M;v[M]=b;
}
void add(int a,int b)
{
add_e(a,b);add_e(b,a);
}
void insertt(char *s)
{
int len=strlen(s);
int cur=root;
for(int i=0;i<len;i++)
{
int c=s[i]-'a';
if(!ch[cur][c])
{
ch[cur][c]=++cnt;
memset(ch[cnt],0,sizeof(ch[cnt]));
fa[cnt]=cur;
}
cur=ch[cur][c];
}
}
void build_f()
{
h=t=0;fail[root]=root;
for(int i=0;i<26;i++)
{
if(!ch[root][i])
{
ch[root][i]=root;continue;
}
fail[ch[root][i]]=root;
q[t++]=ch[root][i];
}
while(h!=t)
{
int cur=q[h++];
for(int i=0;i<26;i++)
{
if(!ch[cur][i])
{
ch[cur][i]=ch[fail[cur]][i];
}
else
{
fail[ch[cur][i]]=ch[fail[cur]][i];
q[t++]=ch[cur][i];
}
}
}
}
void dfs1(int x,int ff=0)
{
dfsn[x]=++pv;
for(int i=fir[x],kk=v[i];i;i=nxt[i],kk=v[i])
{
if(kk==ff)continue;
dfs1(kk,x);
}
ln[x]=pv; return;
}
struct node
{
int laz,maxx;
}no[maxn<<2];
void push_up(int x)
{
no[x].maxx=max(no[ls].maxx,no[rs].maxx);
}
void push_down(int x)
{
if(no[x].laz)
{
no[ls].maxx=max(no[x].laz,no[ls].maxx);
no[rs].maxx=max(no[x].laz,no[rs].maxx);
no[ls].laz=max(no[x].laz,no[ls].laz);
no[rs].laz=max(no[x].laz,no[rs].laz);
no[x].laz=0;
}
}
void build(int x,int l,int r)
{
no[x].laz=0;
no[x].maxx=0;
if(l==r)
{
return;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
push_up(x);
}
void update(int x,int l,int r,int L,int R,int val)
{
if(L<=l&&r<=R)
{
no[x].maxx=max(no[x].maxx,val);
no[x].laz=max(no[x].laz,val);
return;
}
int mid=(l+r)>>1;
push_down(x);
if(L<=mid) update(ls,l,mid,L,R,val);
if(R>mid) update(rs,mid+1,r,L,R,val);
push_up(x);
}
int query(int x,int l,int r,int pl)
{
if(l==r) return no[x].maxx;
push_down(x);
int mid=(l+r)>>1;
if(pl<=mid) return query(ls,l,mid,pl);
if(pl>mid) return query(rs,mid+1,r,pl);
push_up(x);
}
int main()
{
int t;
scanf("%d",&t);
int tot=0;
while(t--)
{
cnt=0;
root=0;
memset(ch[0],0,sizeof(ch[0]));
memset(fir,0,sizeof(fir));
memset(fa,0,sizeof(fa));
memset(fail,0,sizeof(fail));
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s%d",str+pos[i-1],&cc[i]);
insertt(str+pos[i-1]);
pos[i]=pos[i-1]+strlen(str+pos[i-1]);
}
build_f();
M=0,pv=0;
for(int i=1;i<=cnt;i++)
{
add(fail[i],i);
}
dfs1(0,0);
build(1,1,pv);
int mx=0,tmp;
for(int i=1;i<=n;i++)
{
tmp=0;
int now=root;
for(int j=pos[i-1];j<pos[i];j++)
{
now=ch[now][str[j]-'a'];
tmp=max(tmp,query(1,1,pv,dfsn[now]));
}
mx=max(tmp+cc[i],mx);
update(1,1,pv,dfsn[now],ln[now],tmp+cc[i]);
}
printf("Case #%d: %d\n",++tot,mx);
}
}