模板 于是他错误的点名开始了
时间复杂度 O ( n ∣ S ∣ ) O(n|S|) O(n∣S∣)
cpp
const int N=1e6+5,C=1e6+10,mod=1e9+7,inf=1e9+10;
struct trie{
//计数数组 访问次数 孩子数组
int cnt[N],tp[N],ch[N][30];
int id=0;
void insert(string s){//插入每一个字符串
int p=0;
for(auto c:s){
int j=c-'a';
if(!ch[p][j])ch[p][j]=++id;//孩子没有编号的安排编号
p=ch[p][j];//跳到孩子
//cnt[p]++放在这里 记录经过的次数
}
cnt[p]++;//记录每个串个数
}
void query(string s){//询问每个字符串状态
int p=0;//和insert大致相同
for(auto c:s){
int j=c-'a';
if(!ch[p][j])return cout<<"WRONG"<<endl,void();
p=ch[p][j];
}
tp[p]++;
if(cnt[p]==0)cout<<"WRONG"<<endl;
else if(tp[p]>1)cout<<"REPEAT"<<endl;
else cout<<"OK"<<endl;
}
}t;
void solve() {
int n,m;cin>>n;
forr(i,1,n){
string s;cin>>s;
t.insert(s);
}
cin>>m;
forr(i,1,m){
string s;cin>>s;
t.query(s);
}
cout<<t.id<<endl;
}
最长异或路径
cpp
const int N=1e6+5,C=1e6+10,mod=1e9+7,inf=1e9+10;
struct trie{
int ch[N*32][2],id=0;
void insert(int s){
int p=0;
reforr(i,0,30){
int j=s>>i&1;//从高位到低位 从上到下
if(!ch[p][j])ch[p][j]=++id;
p=ch[p][j];
}
}
int query(int s){
int p=0,res=0;
reforr(i,0,30){
int j=s>>i&1;
if(ch[p][!j]){
res+=(1<<i);
p=ch[p][!j];
}else p=ch[p][j];
}
return res;
}
}t;
vector<pii>e[N];
int sum[N];
void dfs(int now,int fa){
for(auto [x,w]:e[now]){
if(fa==x)continue;
sum[x]=w^sum[now];
dfs(x,now);
}
}
void solve() {
int n;cin>>n;
forr(i,1,n-1){
int u,v,w;cin>>u>>v>>w;
e[u].push_back({v,w});
e[v].push_back({u,w});
}
dfs(1,0);
forr(i,1,n)t.insert(sum[i]);//把x->1的异或路径值放进去
int ans=0;
forr(i,1,n)ans=max(ans,sum[i]);
forr(i,1,n)ans=max(ans,t.query(sum[i]));//两两最大异或和
cout<<ans<<endl;
}