RE求救!!!!

P1600 [NOIP2016 提高组] 天天爱跑步

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)


|