谁能解释一下为什么开两倍数组空间就 AC 了
查看原帖
谁能解释一下为什么开两倍数组空间就 AC 了
683859
complete_binary_tree楼主2024/4/2 15:15

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 了。

为什么?

2024/4/2 15:15
加载中...