树链剖分0pts求助
查看原帖
树链剖分0pts求助
571841
ZVitality楼主2023/3/21 13:41

rt,第二个样例过不了。

#include <bits/stdc++.h>
using namespace std;

#define int long long

inline int Read() {
  int x = 0 , f = 1;
  char c = getchar();
  for( ; c < '0' || c > '9' ; c = getchar() ) f ^= ( c == '-' );
  for( ; c >= '0' && c <= '9' ; c = getchar() ) x = ( x << 3 ) + ( x << 1 ) + ( c ^ 48 );
  return f ? x : -x;
}

const int _ = 1e5 + 5;

struct Edge { int v , nxt ; } e[_*2];
int head[_] , ecnt;
void Add( int u , int v ) { e[ ++ecnt ] = Edge{ v , head[ u ] } ; head[ u ] = ecnt ; }

int dep[_] , fa[_] , siz[_] , dfn[_] , son[_] , top[_] , cnt;
int a[_] , b[_];
int n , q;

template< int Maxx >
struct SegmentTree {
  
  const int NONE = -1145141919810;
  
  int tree[ Maxx * 4 ] , covertag[ Maxx * 4 ];
  
  void PushUp( int p ) { tree[ p ] = tree[ p * 2 ] + tree[ p * 2 + 1 ] ; }
  
  void PushDown( int l , int r , int p ) {
    if( covertag[ p ] != NONE ) {
      int mid = ( l + r ) / 2;
      covertag[ p * 2 ] = covertag[ p * 2 + 1 ] = covertag[ p ];
      tree[ p * 2 ] = covertag[ p ] * ( mid - l + 1 );
      tree[ p * 2 + 1 ] = covertag[ p ] * ( r - mid );
      covertag[ p ] = NONE;
    }
  }
      
  
  void BuildTree( int a[] , int l , int r , int p ) {
  	if( l == r ) {
  	  tree[ p ] = a[ l ];
  	  return;
	}
	int mid = ( l + r ) / 2;
	BuildTree( a , l , mid , p * 2 ) , BuildTree( a , mid + 1 , r , p * 2 + 1 );
	PushUp( p );
  }
  
  void Assign( int l , int r , int x , int y , int val , int p ) {
    if( x <= l && r <= y ) {
      tree[ p ] = ( r - l + 1 ) * val;
      covertag[ p ] = val;
      return;
    }
    if( covertag[ p ] != NONE ) PushDown( l , r , p );
    int mid = ( l + r ) / 2;
    if( x <= mid ) Assign( l , mid , x , y , val , p * 2 );
    if( y > mid ) Assign( mid + 1 , r , x , y , val , p * 2 + 1 );
    PushUp( p );
  }
};

SegmentTree<_> tree;

void DFS1( int x ) {
  dep[ x ] = dep[ fa[ x ] ] + 1 , siz[ x ] = 1;
  for( int i = head[ x ] ; i ; i = e[ i ].nxt ) {
  	int y = e[ i ].v;
  	if( !dep[ y ] ) {
  	  fa[ y ] = x;
  	  DFS1( y );
  	  siz[ x ] += siz[ y ];
  	  if( siz[ y ] > siz[ son[ x ] ] ) son[ x ] = y;
    }
  }
}

void DFS2( int x ) {
  dfn[ x ] = ++cnt;
  if( son[ x ] ) {
  	top[ son[ x ] ] = top[ x ];
  	DFS2( son[ x ] );
  }
  for( int i = head[ x ] ; i ; i = e[ i ].nxt ) {
  	int y = e[ i ].v;
  	if( !top[ y ] ) {
  	  top[ y ] = y;
  	  DFS2( y );
    }
  }
}

void Change( int x , int y , int val ) {
  while( top[ x ] != top[ y ] ) {
  	if( dep[ top[ x ] ] < dep[ top[ y ] ] ) swap( x , y );
  	tree.Assign( 1 , n , dfn[ top[ x ] ] , top[ x ] , val , 1 );
  	x = fa[ top[ x ] ];
  }
  if( dep[ x ] > dep[ y ] ) swap( x , y );
  tree.Assign( 1 , n , dfn[ x ] , dfn[ y ] , val , 1 );
}

signed main() {
  freopen( "A.txt" , "r" , stdin );
  n = Read();
  for( int i = 2 ; i <= n ; i++ ) {
  	int x = Read() + 1;
  	Add( x , i );
  }
  DFS1( 1 ) , fa[ 1 ] = 1 , top[ 1 ] = 1 , DFS2( 1 );
  q = Read();
  tree.BuildTree( a , 1 , n , 1 );
  while( q-- ) {
  	string s;
  	cin >> s;
  	int x = Read() + 1 , a = tree.tree[ 1 ];
  	if( s == "install" ) Change( 1 , x , 1 );
    else tree.Assign( 1 , n , dfn[ x ] , dfn[ x ] + siz[ x ] - 1 , 0 , 1 );
    int b = tree.tree[ 1 ];
    cout << abs( a - b ) << '\n';
  }
  return 0;
}
2023/3/21 13:41
加载中...