paulyc @ 2020-09-22 22:49:26
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<fstream>
#define ll long long
#define ld long double
//#define test
using namespace std;
const int MAX = 300000+5;
const int INF = 0x7f7f7f7f;
const int MOD = 1e9+7;
int idx;
int n , m;
int tot , cnt;
int val[MAX] , head[MAX];
int fa[MAX] , size[MAX] , son[MAX] , dep[MAX];
int top[MAX] , id[MAX] , rk[MAX];
int wup[MAX] , wdw[MAX] , ans[MAX];
struct edge
{
int to , next;
}e[MAX*4];
struct node{
int w , id;
bool operator < ( const node x ) const
{ return (w==x.w)? (id<x.id):(w<x.w); }
};
class ArrayTree
{
public:
int tree[MAX];
inline void Update( int p , int k );
inline int Query( int p );
private:
inline int lowbit( int x );
};
class Help
{
public:
ArrayTree num;
node arr[MAX];
inline void Init( int w[] );
inline void Update( int p , int q , int k );
inline void Statistics( );
}help[2];
inline void ArrayTree::Update( int p , int k )
{
for( int i = p ; i <= n ; i += lowbit(i) )
tree[i] += k;
}
inline int ArrayTree::Query( int p )
{
int sum = 0;
for( int i = p ; i ; i -= lowbit(i) )
sum += tree[i];
return sum;
}
inline int ArrayTree::lowbit( int x )
{
return x&(-x);
}
inline void Help::Init( int w[] )
{
for( int i = 1 ; i <= n ; ++i )
arr[i] = (node){ w[i] , i };
sort( arr+1 , arr+n+1 );
for( int i = 1 ; i <= n ; ++i )
num.tree[i] = 0;
}
inline void Help::Update( int p , int q , int k )
{
int l = lower_bound( arr+1 , arr+n+1 , (node){k,p} ) - arr;
int r = lower_bound( arr+1 , arr+n+1 , (node){k,q} ) - arr;
while( arr[r].w != k || arr[r].id > q ) r--;
if( l > r || arr[l].w != k || l > n || r > n ) return ;
num.Update( l , 1 );
num.Update( r+1 , -1 );
}
inline void Help::Statistics( )
{
for( int i = 1 ; i <= n ; ++i )
ans[rk[arr[i].id]] += num.Query( i );
}
inline int Read()
{
char ch; int res ;
ch = getchar(); res = 0;
while( !isdigit(ch) ) ch = getchar();
while( isdigit(ch) )
{ res = (res<<3) + (res<<1) + ch-48; ch = getchar(); }
return res;
}
inline void AddEdge( int u , int v )
{
e[++cnt] = (edge){ v , head[u] };
head[u] = cnt;
}
void dfs1( int u , int fath )
{
idx++;
if( idx > 40000 ) return;
cout << u << endl;
fa[u] = fath , size[u] = 1 , dep[u] = dep[fath] + 1;
for( int i = head[u] ; i ; i = e[i].next )
{
int v = e[i].to;
if( e[i].to == fath ) continue;
dfs1( e[i].to , u );
size[u] += size[v];
if( size[v] > size[son[u]] )
son[u] = v;
}
}
void dfs2( int u , int t )
{
top[u] = t , id[u] = ++tot , rk[tot] = u;
if( !son[u] ) return; dfs2( son[u] , t );
for( int i = head[u] ; i ; i = e[i].next )
{
int v = e[i].to;
if( v != fa[u] && v != son[u] )
dfs2( v , v );
}
}
inline void MakeValue( )
{
for( int i = 1 ; i <= n ; ++i )
{
int u = rk[i];
wup[i] = val[u] + dep[u];
wdw[i] = val[u] - dep[u];
}
help[0].Init( wup );
help[1].Init( wdw );
}
inline void Init()
{
dfs1( 1 , 0 );
//dfs2( 1 , 1 );
//MakeValue( );
}
inline void LCA( int u , int v )
{
bool change = false;
int len = 0;
int stu = 0;
int std = 0;
int uu = u;
int vv = v;
while( top[uu] != top[vv] )
{
if( dep[top[uu]] < dep[top[vv]] )
swap( uu , vv );
len = len + dep[uu] - dep[fa[top[uu]]];
uu = fa[top[uu]];
}
if( dep[uu] > dep[vv] ) swap( uu , vv );
len = len + dep[vv] - dep[uu];
while( top[u] != top[v] )
{
if( dep[top[u]] < dep[top[v]] )
{
swap( u , v );
change = change xor 1;
}
int wu = stu + dep[u];
int wd = len - std - dep[u];
int delta = dep[u] - dep[fa[top[u]]];
if( change == false )
{
help[0].Update( id[top[u]] , id[u] , wu );
stu += delta;
}
else
{
help[1].Update( id[top[u]] , id[u] , wd );
std += delta;
}
u = fa[top[u]];
}
if( dep[u] < dep[v] )
{
swap( u , v );
change = change xor 1;
}
int wu = stu + dep[u];
int wd = len - std - dep[u];
if( change == false )
help[0].Update( id[v] , id[u] , wu );
else
help[1].Update( id[v] , id[u] , wd );
}
int main()
{
freopen( "fuck.txt" , "r" , stdin );
cout << '*' << endl;
n = Read() , m = Read();
for( int i = 1 ; i <= n-1 ; ++i )
{
int u = Read();
int v = Read();
AddEdge( u , v );
AddEdge( v , u );
}
for( int i = 1 ; i <= n ; ++i )
val[i] = Read();
Init();
cout << '*' << endl;
/*
for( int i = 1 ; i <= m ; ++i )
{
int u = Read();
int v = Read();
LCA( u , v);
}
help[0].Statistics( );
help[1].Statistics( );
for( int i = 1 ; i <= n ; ++i )
printf( "%d " , ans[i] );
putchar( '\n' );
*/
return 0;
}
第五个点(一条链)在跑dfs1时直接炸掉,求救
by paulyc @ 2020-09-22 22:49:57
(指树剖的第一个dfs)