对应2018 计蒜之道 初赛 第二场的 D. 阿里巴巴的手机代理商(困难)
typedef long long ll;
struct node{int next[N][26],L,root[N],time;
ll c[N];
int newnode(int x){
L++;
for(int i=0;i<26;i++)
next[L][i]=next[x][i];
c[L]=c[x];
return L;
}
void init(){
L=1;
for(int i=0;i<26;i++)
next[L][i]=0;
c[L]=time=0;
}
void insert(char *s,int k)
{
int n=strlen(s);
root[time+1]=newnode(root[time]);
int now=root[++time];
c[now]+=k;
for(int i=n-1;i>=0;i--){
int x=s[i]-'a';
next[now][x]=newnode(next[now][x]);
now=next[now][x];
c[now]+=k;
}
}
ll query(char *s,int k,int f)
{
int n=strlen(s);
int now=root[k];
for(int i=n-1;i>=0;i--){
int x=s[i]-'a';
now=next[now][x];
if(!now)return 0;
}
ll ans=c[now];
for(int i=0;i<26&&f;i++)
ans-=c[next[now][i]];
return ans;
}
bool erase(char *s)
{
ll have=query(s, time, 1);
if(!have)return 1;
insert(s, -have);
return 0;
}
void update(char *s, char *cc)
{
ll have=query(s, time, 0);
if(!have){
puts("Empty");
return;
}
if(query(cc, time, 0)){
puts("Conflict");
return;
}
root[time+1]=newnode(root[time]);
int now=root[++time];
c[now]-=have;
for(int i=strlen(s)-1;i;i--){
int x=s[i]-'a';
next[now][x]=newnode(next[now][x]);
now=next[now][x];
c[now]-=have;
}
int tmp=next[now][s[0]-'a'];
next[now][s[0]-'a']=0;
root[time]=newnode(root[time]);
now=root[time];
c[now]+=have;
for(int i=strlen(cc)-1;i;i--){
int x=cc[i]-'a';
next[now][x]=newnode(next[now][x]);
now=next[now][x];
c[now]+=have;
}
next[now][cc[0]-'a']=tmp;
//printf("-----%d %s %s\n",have,s,cc);
}
}trie;