rt,代码:
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N = 1e5 + 5;
namespace fastio{
template< typename T >
void read( T& x );
template< typename T, typename ... Args >
void read( T& a, Args& ...b ){
read( a ), read( b... );
}
template< typename T >
void read( T& x ){
x = 0;T f = 1;
char ch = getchar();
while( ( ch < '0' || ch > '9' ) && ch != EOF ){
if( ch == '-' ) f = -1;
ch = getchar();
}
while( ch >= '0' && ch <= '9' ){
x = x * 10 + ch - 48;
ch = getchar();
}
x *= f;
return ;
}
};
using fastio::read;
struct treezu{
int n;
vector<int> t;
void csh( int _n ){ n = _n + 1; t.resize( _n + 2 ); }
void ins( int pos, int x ){
// printf("!%d %d", pos, x);
if( pos < 0 ) return ;
pos++;
if( pos <= 0 ) return ;
for( ; pos <= n; pos += ( pos & ( -pos ) ) ) t[pos] += x;
// printf("OK.\n");
}
int find( int pos ){
if( pos < 0 ) return 0;
pos++;
if( pos > n ) pos = n;
if( pos == 0 ) return 0;
// printf("!%d\n", pos);
// for( int i = 1; i <= n; ++i) printf("%d ", t[i]);
// puts("");
int ans = 0;
for( ; pos; pos -= ( pos & ( -pos ) ) ) ans += t[pos];
return ans;
}
};
int fa[20][N], deep[N], val[N], n, m, mxdeep;
treezu s1[N], s2[N];
struct edge{ int v, nxt; } e[N << 1], edfs[N << 1];
int head[N], headdfs[N], cnt, cntdfs;
void add( int u, int v ){ e[++cnt] = { v, head[u] }; head[u] = cnt; }
void adddfs( int u, int v ){ edfs[++cnt] = { v, headdfs[u] }; headdfs[u] = cnt;
}
void dfs1( int u, int _fa ){
// printf("!%d\n", u);
fa[0][u] = _fa, deep[u] = deep[_fa] + 1;
mxdeep = max( mxdeep, deep[u] );
for( int i = head[u]; i; i = e[i].nxt ){
int v = e[i].v;
if( v == _fa ) continue;
dfs1( v, u );
}
return ;
}
void prest(){
for( int i = 1; i <= 18; ++i )
for( int j = 1; j <= n; ++j )
fa[i][j] = fa[i - 1][fa[i - 1][j]];
// printf("OK.complete\n");
return ;
}
int jump_up( int now, int up ){
int i = 0;
while( up ){
if( up & 1 ) now = fa[i][now];
up >>= 1, ++i;
}
return now;
}
int find_lca( int a, int b ){
if( a == b ) return a;
if( deep[a] < deep[b] ) swap( a, b );
a = jump_up( a, deep[a] - deep[b] );
int i = 18;
if( a == b ) return a;
for( ; ~i; --i ){
if( fa[i][a] != fa[i][b] ) a = fa[i][a], b = fa[i][b];
}
return a == b ? a : fa[0][a];
}
int dist( int a, int b ){
if( a == 0 ) return deep[b];
else if( b == 0 ) return deep[a];
int _lca = find_lca( a, b );
return deep[a] + deep[b] - 2 * deep[_lca];
}
int mxzs[N], jds[N], fadfs[N];
bool vis[N];
queue<int> q;
void findzx( int u, int fa ){
mxzs[u] = 0, jds[u] = 1, q.push( u );
for( int i = head[u]; i; i = e[i].nxt ){
int v = e[i].v;
if( v == fa || vis[v] ) continue;
findzx( v, u );
mxzs[u] = max( mxzs[u], jds[v] ), jds[u] += jds[v];
}
return ;
}
int dfz( int root, int _fa ){
findzx( root, 0 );
int jd = q.size();
while( !q.empty() ){
int u = q.front();q.pop();
mxzs[u] = max( mxzs[u], jd - jds[u] );
if( mxzs[u] < mxzs[root] ) root = u;
}
s1[root].csh( jd + 3 ), s2[root].csh( jd + 3 );
vis[root] = 1;
fadfs[root] = _fa, adddfs( _fa, root );
for( int i = head[root]; i; i = e[i].nxt ){
int v = e[i].v;
if( v == _fa || vis[v] ) continue;
int sonroot = dfz( v, root );
}
return root;
}
void change( int u, int val ){
int f = u;
for( ; u; u = fadfs[u] ){
s1[u].ins( dist( u, f ), val );
/*if( fadfs[u] )*/ s2[u].ins( dist( fadfs[u], f ), val );
}
return ;
}
int find( int u, int k ){
int x = u, l = 0, ans = 0;
for( ; x; l = x, x = fadfs[x] ){
//printf("!%d", x);
int d = dist( x, u );
if( k >= d ){
ans += s1[x].find( k - d );
if( l ) ans -= s2[l].find( k - d );
}
}
return ans;
}
int last = 0;
signed main(){
read( n, m );
for( int i = 1; i <= n; ++i ) read( val[i] );
for( int i = 1; i < n; ++i ){ int u, v; read( u, v ); add( u ,v ), add( v, u ); }
dfs1( 1, 0 );
prest();
dfz( 1, 0 );
for( int i = 1; i <= n; ++i ) change( i, val[i] );
for( int i = 1; i <= m; ++i ){
int op, x, k;
read( op, x, k );
x ^= last, k ^= last;
if( op ){
change( x, k - val[x] ), val[x] = k;
}
else{
last = find( x, k );
printf( "%d\n", last );
}
}
// printf("%d\n", dist(3, 7));
return 0;
}
RE,只 A 第三个点。
如果把 const int N = 1e5 + 5; 改成 const int N = 2e5 + 5; 就 AC 了。
为什么?