问题一
一个以1为根的带权二叉树,每个点都有个权值 vi v i 。
若点 b b 在 的左子树中,且 a a 到 的距离为 vb v b ,则称 b b 为 的左关联点
若点 b b 在 的右子树中,且 a a 到 的距离为 vb v b ,则称 b b 为 的右关联点
求每一个点的左右关联点个数。
倍增快速跳即可,代码如下:
#include <bits/stdc++.h>
using namespace std;
#define R register
#define Maxn 1000005
int n,v[Maxn],lson[Maxn],rson[Maxn];
int f[Maxn][20],ans[Maxn][2];
template <class RME> inline void read(R RME &x)
{
x=0;R bool f=0;R char ch;
for(ch=getchar();ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);
if(f) x=-x;
}
int main()
{
read(n);
for (R int i=1;i<=n;++i) read(v[i]);
for (R int i=1;i<=n;++i) read(lson[i]),read(rson[i]),f[lson[i]][0]=f[rson[i]][0]=i;
f[0][0]=0;
for (R int j=1;j<=18;++j)
for (R int i=1;i<=n;++i)
{
f[i][j] = f[f[i][j-1]][j-1];
}
for (R int i=1;i<=n;++i)
{
R int now=i;
for (R int j=0;(1<<j)<=v[i]-1;++j)if((v[i]-1)&(1<<j)) now = f[now][j];
R int fa=f[now][0];
if(now==lson[fa]) ans[fa][0]++;
else if(now==rson[fa]) ans[fa][1]++;
}
for (R int i=1;i<=n;++i) printf("%d %d\n",ans[i][0],ans[i][1]);
return 0;
}
问题二
问题一中的
vb
v
b
全部替换成
va
v
a
.。
简单推一下即可,不会爆栈。
代码如下:
#include <bits/stdc++.h>
using namespace std;
#define R register
#define Maxn 1000005
int tesc;
int next_int()
{
register char ch;
while(ch = getchar(), ch < '0' || ch > '9') ;
register int ans = ch - '0';
while(ch = getchar(), '0' <= ch && ch <= '9') ans = ans * 10 + ch - '0';
return ans;
}
int n,v[Maxn],lson[Maxn],rson[Maxn],dep[Maxn],cnt[Maxn],ans[Maxn][2];
void dfs(R int pos)
{
cnt[dep[pos]] ++;
if(lson[pos])
{
dep[lson[pos]] = dep[pos] + 1;
R int tmp = cnt[dep[pos]+v[pos]];
dfs(lson[pos]);
ans[pos][0] = cnt[dep[pos]+v[pos]]-tmp;
}
if(rson[pos])
{
dep[rson[pos]] = dep[pos] + 1;
R int tmp = cnt[dep[pos]+v[pos]];
dfs(rson[pos]);
ans[pos][1] = cnt[dep[pos]+v[pos]] - tmp;
}
}
int main()
{
freopen("test.in","r",stdin);
/*
int size = 64 << 20;
char *p = (char*)malloc(size) + size;
__asm__("movl %0, %%esp\n" :: "r"(p));
*/
n = next_int();
for(register int i = 1; i <= n; ++i) v[i] = next_int();
for(register int i = 1; i <= n; ++i) lson[i] = next_int(), rson[i] = next_int();
dfs(1);
R const int P = 1004535809, Q = 998244353;
R int A = 2341, B = 4123;
for(register int i = 1; i <= n; ++i)
{
A = ((long long) A * n + ans[i][0]) % P; B = ((long long) B * n + ans[i][0]) % Q;
A = ((long long) A * n + ans[i][1]) % P; B = ((long long) B * n + ans[i][1]) % Q;
}
printf("%d %d\n",A,B);
return 0;
}
血的教训:
倍增注意for的顺序,先for0-32!
for (R int j=1;j<=18;++j)
for (R int i=1;i<=n;++i)
{
f[i][j] = f[f[i][j-1]][j-1];
}
就这玩意儿调了我一晚上。。