思路将子树状态改成特定整数,哈希表自然溢出,满足条件后将字数状态再次压缩(类似回文串),从叶子节点上搜到根节点
#include <bits/stdc++.h>
using namespace std;
#define int unsigned long long
const int N=3e6+100;
int n;
int a[N];
int b[N];
int p[N];
int k[N];
struct node{
int l,r,son,val;//子节点个数&hash
};
map<int,node>tr;
bool check(int l,int r){
int cnt=0;
while(l){
k[++cnt]=l%10;
l/=10;
}
while(r){
int s=r%10;
if(k[cnt--]!=s)return false;
r/=10;
}
return true;
}
int dfs_cs(int x){
if(tr[x].l!=-1)tr[x].son+=dfs_cs(tr[x].l)+1;
if(tr[x].r!=-1)tr[x].son+=dfs_cs(tr[x].r)+1;
return tr[x].son;
}
int ans=1;
void dfs_ca(int x){
int l=tr[x].l;
int r=tr[x].r;
if(l==-1&&r==-1)return;
if(l!=-1)dfs_ca(l);
if(r!=-1)dfs_ca(r);
l=max(0ull,l);
r=max(0ull,r);
if(b[l]==a[r]&&b[r]==a[l]){
ans=max(ans,tr[x].son+1);
}
a[x]=a[r]+(a[x]+a[l]*p[tr[x].val])*p[tr[r].val];
b[x]=b[l]+(b[x]+b[r]*p[tr[x].val])*p[tr[l].val];
tr[x].val=tr[x].val+tr[l].val+tr[r].val;
}
signed main(){
cin>>n;
int cnt=0;
p[0]=1;
for(int i=1;i<=n;i++){
cin>>a[i];
b[i]=a[i];
int s=a[i];
int idx=0;
while(s){
idx++;
s/=10;
}
tr[i].val=idx;
cnt+=idx;
}
for(int i=1;i<=cnt+10;i++){
p[i]=p[i-1]*10;
}
for(int i=1;i<=n;i++){
int l,r;
cin>>l>>r;
tr[i].l=l;
tr[i].r=r;
}
dfs_cs(1);
dfs_ca(1);
cout<<ans;
return 0;
}
28pts->36pts->64pts,问题 WA+TLE 下载测试点才想起点权一致时,就压缩整数不一定能看的出来 但咋改不会啊,有dalao能帮一下吗