QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#851598 | #7961. 一棵树 | JZYZ# | WA | 738ms | 58552kb | C++14 | 3.8kb | 2025-01-10 20:59:28 | 2025-01-10 20:59:29 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std ;
typedef long long LL ;
const int N = 5e5+10 ;
// 维护差分数组
int n , K ;
vector<int> E[N] ;
struct nn
{
int ls , rs , siz , val ;
LL tag , sum ;
}t[N] ;//按sum从小到大排序
mt19937 rnd(time(0)) ;
int idx , rt[N] ;
inline int get_node( LL sum )
{
idx ++ ;
t[idx].siz = 1 , t[idx].val = rnd() , t[idx].sum = 0 ;
return idx ;
}
inline void pushup( int p )
{
t[p].siz = t[t[p].ls].siz + t[t[p].rs].siz + 1 ;
}
inline void Assign( int p , LL x )
{
if( !p ) return ;
t[p].sum += x , t[p].tag += x ;
}
inline void pushdown( int p )
{
if( t[p].tag ) {
Assign(t[p].ls,t[p].tag) ;
Assign(t[p].rs,t[p].tag) ;
t[p].tag = 0 ;
}
}
void split( int p , LL sum , int &x , int &y )
{
if( !p ) { x = y = 0 ; return ; }
pushdown(p) ;
if( sum < t[p].sum ) {
y = p ;
split(t[p].ls,sum,x,t[y].ls) ;
}
else {
x = p ;
split(t[p].rs,sum,t[x].rs,y) ;
}
pushup(p) ;
}
int Merge( int p , int q ) // p<q, 合并 p,q, 返回新树的 root
{
if( !p || !q ) return p^q ;
pushdown(p) ; pushdown(q) ;
if( t[p].val < t[q].val ) {
t[q].ls = Merge(p,t[q].ls) ;
pushup(q) ;
return q ;
}
else {
t[p].rs = Merge(t[p].rs,q) ;
pushup(p) ;
return p ;
}
}
int Union( int p , int q ) // 带交合并
{
if( !p || !q ) return p^q ;
pushdown(p) ; pushdown(q) ;
if( t[p].val < t[q].val ) swap(p,q) ;
int tl , tr ;
split(q,t[p].sum,tl,tr) ;//注意这里对于相等的key需要随机调整一下,防止树高过高
t[p].ls = Union(t[p].ls,tl) ; t[p].rs = Union(t[p].rs,tr) ;
pushup(p) ;
return p ;
}
void split1( int p , int num , int &x , int &y ) // 前 num 个为 x
{
if( !p ) { x = y = 0 ; return ; }
pushdown(p) ;
if( t[t[p].ls].siz+1 <= num ) {
x = p ;
split1(t[p].rs,num-(t[t[p].ls].siz+1),t[x].rs,y) ;
}
else {
y = p ;
split1(t[p].ls,num,x,t[y].ls) ;
}
pushup(p) ;
}
LL ans[N] ;
int len ;
void Get( int p )
{
pushdown(p) ;
if( t[p].ls ) Get(t[p].ls) ;
ans[++len] = t[p].sum ;
if( t[p].rs ) Get(t[p].rs) ;
}
int sz[N] ;
void dfs( int x , int fa )
{
rt[x] = get_node(0) ;//f1-f0
sz[x] = 1 ;
for(int t : E[x] ) {
if( t == fa ) continue ;
dfs(t,x) ;
sz[x] += sz[t] ;
rt[x] = Union(rt[x],rt[t]) ;
}
int p = K/2 , tl , tr , tmid ;
// if( x != 1 ) {
// printf("at %d\n" , x ) ;
// len = 0 ;
// Get(rt[x]) ;
// ans[0] = 0 ;
// for(int i = 1 ; i <= len ; i ++ ) {
// ans[i] += ans[i-1] ;
// printf("%lld " , ans[i] ) ;
// }
// printf("\n") ;
// }
if( t[rt[x]].siz <= p ) {
Assign(rt[x],-2) ;
}
else {
// printf("tag 1\n") ;
split1(rt[x],p,tl,tr) ;
Assign(tl,-2) ;
split1(tr,1,tmid,tr) ;
// printf("%d\n" , 4*p+2-2*K ) ;
Assign(tmid,4*p+2-2*K) ;
Assign(tr,2) ;
rt[x] = Merge(tl,Merge(tmid,tr)) ;
}
// if( x != 1 ) {
// printf("at %d\n" , x ) ;
// len = 0 ;
// Get(rt[x]) ;
// ans[0] = sz[x]*K ;
// for(int i = 0 ; i <= len ; i ++ ) {
// if( i ) ans[i] += ans[i-1] ;
// printf("%lld " , ans[i] ) ;
// }
// printf("\n") ;
// }
}
int main()
{
scanf("%d%d" , &n , &K ) ;
int x , y ;
for(int i = 1 ; i < n ; i ++ ) {
scanf("%d%d" , &x , &y ) ;
E[x].push_back(y) ;
E[y].push_back(x) ;
}
dfs(1,0) ;
Get(rt[1]) ;
ans[0] = (n-1)*K ;
for(int i = 1 ; i <= K ; i ++ ) {
ans[i] += ans[i-1] ;
}
printf("%lld\n" , ans[K] ) ;
return 0 ;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Wrong Answer
time: 738ms
memory: 58552kb
input:
499991 31473 1 2 2 3 1 4 2 5 4 6 4 7 6 8 4 9 8 10 6 11 9 12 10 13 10 14 1 15 14 16 3 17 14 18 12 19 13 20 11 21 16 22 16 23 20 24 5 25 16 26 18 27 8 28 15 29 27 30 27 31 26 32 21 33 3 34 27 35 33 36 25 37 22 38 11 39 11 40 17 41 25 42 3 43 3 44 2 45 35 46 25 47 5 48 6 49 41 50 42 51 1 52 39 53 14 54...
output:
-1444938200
result:
wrong answer 1st lines differ - expected: '15734930984', found: '-1444938200'