# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
211259 | Lawliet | Magic Tree (CEOI19_magictree) | C++14 | 1586 ms | 181476 KiB |
This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
const int LOG = 20;
const int MAXK = 3010;
const int MAXN = 100010;
int n, m, k;
int curTime;
int cntNode;
int t[MAXN];
int w[MAXN];
int tin[MAXN];
int tout[MAXN];
int prof[MAXN];
int tab[LOG][MAXN];
int auxT[MAXN];
int auxW[MAXN];
int inv[MAXN];
int compressed[MAXN];
lli dp[MAXK][MAXK];
vector< int > adj[MAXN];
vector< int > auxTree[MAXN];
void DFSCalculate(int cur)
{
for(int i = 0 ; i < adj[cur].size() ; i++)
DFSCalculate( adj[cur][i] );
for(int j = 1 ; j <= k ; j++)
{
lli sum = 0;
if( t[cur] == j ) sum = w[cur];
for(int i = 0 ; i < adj[cur].size() ; i++)
sum += dp[ adj[cur][i] ][j];
dp[cur][j] = max( dp[cur][j - 1] , sum );
}
}
int LCA(int U, int V)
{
if( prof[U] < prof[V] ) swap( U , V );
int d = prof[U] - prof[V];
for(int k = 0 ; k < LOG ; k++)
if( d & (1 << k) ) U = tab[k][U];
if( U == V ) return U;
for(int k = LOG - 1 ; k >= 0 ; k--)
{
if( tab[k][U] != tab[k][V] )
{
U = tab[k][U];
V = tab[k][V];
}
}
return tab[0][U];
}
void DFSInit(int cur, int d)
{
prof[cur] = d;
tin[cur] = ++curTime;
for(int i = 0 ; i < auxTree[cur].size() ; i++)
DFSInit( auxTree[cur][i] , d + 1 );
tout[cur] = curTime;
}
bool cmp(int U, int V) { return tin[U] < tin[V]; }
int getNode(int U)
{
if( compressed[U] == 0 )
{
compressed[U] = ++cntNode;
inv[ cntNode ] = U;
}
return compressed[U];
}
void compressTree()
{
for(int k = 1 ; k <= 3 ; k++)
{
for(int i = 1 ; i <= n ; i++)
{
int jump = tab[k - 1][i];
tab[k][i] = tab[k - 1][jump];
}
}
DFSInit( 1 , 0 );
vector< int > v;
for(int i = 1 ; i <= n ; i++)
if( auxW[i] != 0 ) v.push_back( i );
v.push_back( 1 );
sort( v.begin() , v.end() , cmp );
int sz = v.size();
for(int i = 0 ; i < sz - 1 ; i++)
v.push_back( LCA( v[i] , v[i + 1] ) );
sort( v.begin() , v.end() , cmp );
vector< int > s;
s.push_back( v[0] );
for(int i = 1 ; i < v.size() ; i++)
{
if( v[i] == v[i - 1] ) continue;
while( true )
{
int last = s.back();
if( tin[last] <= tin[ v[i] ] && tout[ v[i] ] <= tout[last] ) break;
s.pop_back();
}
int U = getNode( s.back() );
int V = getNode( v[i] );
adj[ U ].push_back( V );
s.push_back( v[i] );
}
for(int i = 1 ; i <= n ; i++)
{
if( compressed[i] == 0 ) continue;
t[ compressed[i] ] = auxT[i];
w[ compressed[i] ] = auxW[i];
}
n = cntNode;
}
int main()
{
scanf("%d %d %d",&n,&m,&k);
for(int i = 2 ; i <= n ; i++)
{
scanf("%d",&tab[0][i]);
auxTree[ tab[0][i] ].push_back( i );
}
for(int i = 1 ; i <= m ; i++)
{
int node;
scanf("%d",&node);
scanf("%d %d",&auxT[node],&auxW[node]);
}
compressTree();
DFSCalculate( 1 );
printf("%lld\n",dp[1][k]);
}
Compilation message (stderr)
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |