144. 最长异或值路径
思路:求dn到根节点的异或和,存到字典树中求最大疑惑和即可。因为x,y,以上的异或和会消掉。
#include <bits/stdc++.h>
using namespace std;
const int u=100010;
#define fir(i,a,b) for(int i=a;i<=b;i++)
#define fic(i,a,b) for(int i=a;i>=b;i--)
int ver[2*u],edge[2*u],Next[2*u],head[u],v[u],val[u*32],a[u*32][2],f[u],trie[2*u][31];
int n,tot,i,ans,x,y,z;
inline int read()//快速读入
{
char ch=getchar();
int p=1,q=0;
for(; ch!='-' && ch<'0' || ch>'9'; ch=getchar());
if (ch=='-')
p=-p;
for(; ch>='0' && ch<='9'; q=q*10+ch-'0',ch=getchar());
return p*q;
}
inline void add(int x,int y,int z)//链式前项星
{
ver[++tot]=y;
edge[tot]=z;
Next[tot]=head[x];
head[x]=tot;
}
inline void dfs(int x)
{
v[x]=1;
for(int i=head[x]; i; i=Next[i])//枚举x节点所有的路径
if(!v[ver[i]])
{
f[ver[i]]=f[x]^edge[i];
dfs(ver[i]);
}
}
void insert(int x,int y,int now)
{
if(y<0)
{
val[x]=now;
return;
}
int z=(now>>y)&1;//取出第y位
if(!a[x][z])
a[x][z]=++tot;
insert(a[x][z],y-1,now);
}
int Search(int x,int y,int now)
{
if(y<0)
return val[x];
int z=(now>>y)&1;//取出第y位
if(a[x][z^1])
return Search(a[x][z^1],y-1,now);
else
return Search(a[x][z],y-1,now);
}
int main()
{
n=read();
for(i=1; i<n; i++)
{
x=read();
y=read();
z=read();
x++;
y++;
add(x,y,z);
add(y,x,z);
}
dfs(1);
tot=1;
ans=0;
insert(1,30,0);
for(i=1; i<=n; i++)
{
ans=max(ans,f[i]^Search(1,30,f[i]));//选取最大值
insert(1,30,f[i]);
}
cout<<ans<<endl;
return 0;
}
142. 前缀统计
- tot初始为1
- b[u]而非b[tot],因为可能有些不是新建的节点
#include<bits/stdc++.h>
using namespace std;
inline long long read(){
long long num=0;int z=1;char c=getchar();
if(c=='-') z=-1;
while((c<'0'||c>'9')&&c!='-') c=getchar();
if(c=='-') z=-1,c=getchar();
while(c>='0'&&c<='9') num=(num<<1)+(num<<3)+(c^48),c=getchar();
return z*num;
}
#define _for(i,a,b) for(int i=a;i<=b;i++)
char s[1000006];
int c[1000006][30],b[1000006],tot=1;
void work()
{
int len=strlen(s+1);
int u=1;
_for(i,1,len)
{
int o=s[i]-'a';
if(!c[u][o])c[u][o]=++tot;
u=c[u][o];
}
b[u]++;
}
int ask()
{
int len=strlen(s+1);
int u=1;
int ans=0;
_for(i,1,len)
{
int o=s[i]-'a';
u=c[u][o];
if(u==0)return ans;
ans+=b[u];
}
return ans;
}
int main(){
int n,m;
n=read();m=read();
_for(i,1,n) scanf("%s",s+1),work();
_for(i,1,m)scanf("%s",s+1),printf("%d\n",ask());
return 0;
}