题目链接:Magic Number
看懂题目,就知道怎么做
#include <stdio.h>
#include <vector>
#include <string.h>
#include <algorithm>
using namespace std ;
typedef long long LL ;
typedef pair < int , int > pii ;
#define clr( a , x ) memset ( a , x , sizeof a )
const int MAXN = 5005 ;
const int N = 1000005 ;
int n , m , q ;
int a[MAXN] , b[MAXN] , c[N] ;
int f[MAXN][15] , dep[MAXN] ;
int dfn[MAXN] , dfs_time ;
vector < int > G[MAXN] ;
int lca ( int x , int y ) {
if ( dep[x] < dep[y] ) swap ( x , y ) ;
for ( int i = 14 ; ~i ; -- i ) {
if ( dep[x] - ( 1 << i ) >= dep[y] ) x = f[x][i] ;
}
if ( x == y ) return x ;
for ( int i = 14 ; ~i ; -- i ) {
if ( ~f[x][i] && ~f[y][i] && f[x][i] != f[y][i] ) {
x = f[x][i] ;
y = f[y][i] ;
}
}
return f[x][0] ;
}
void dfs ( int u ) {
dfn[u] = ++ dfs_time ;
for ( int i = 0 ; i < G[u].size () ; ++ i ) {
dfs ( G[u][i] ) ;
}
}
int cmp ( const int& a , const int& b ) {
return dfn[a] < dfn[b] ;
}
void scanf ( int& x , char c = 0 ) {
while ( ( c = getchar () ) < '0' ) ;
x = c - '0' ;
while ( ( c = getchar () ) >= '0' ) x = x * 10 + c - '0' ;
}
void solve () {
clr ( f , -1 ) ;
dfs_time = 0 ;
scanf ( "%d%d" , &n , &m ) ;
for ( int i = 1 ; i <= n ; ++ i ) {
G[i].clear () ;
}
for ( int i = 1 ; i <= m ; ++ i ) {
scanf ( a[i] ) ;
a[i] ++ ;
}
sort ( a + 1 , a + m + 1 ) ;
int j = 1 ;
for ( int i = 1 ; i <= n ; ++ i ) {
int x = -1 , l = i * ( i - 1 ) / 2 + 1 , r = i * ( i + 1 ) / 2 ;
while ( j <= m && a[j] <= r ) {
int t = a[j ++] - l + 1 ;
if ( t >= i ) continue ;
if ( x == -1 ) x = t ;
else x = lca ( x , t ) ;
}
if ( x == -1 ) x = 0 ;
dep[i] = dep[x] + 1 ;
f[i][0] = x ;
G[x].push_back ( i ) ;
for ( int j = 1 ; j < 15 ; ++ j ) {
if ( ~f[i][j - 1] ) f[i][j] = f[f[i][j - 1]][j - 1] ;
}
}
dfs ( 0 ) ;
scanf ( "%d%d" , &q , &m ) ;
for ( int i = 1 ; i <= q ; ++ i ) {
scanf ( b[i] ) ;
}
for ( int i = 1 ; i <= m ; ++ i ) {
scanf ( c[i] ) ;
c[i] ++ ;
}
sort ( c + 1 , c + m + 1 ) ;
int tot = 0 ;
j = 1 ;
for ( int i = 1 ; i <= q ; ++ i ) {
int l = tot + 1 , r = tot + b[i] , n1 = 0 ;
while ( j <= m && c[j] <= r ) {
int t = c[j ++] - l + 1 ;
if ( t <= n ) a[n1 ++] = t ;
}
sort ( a , a + n1 , cmp ) ;
int ans = 0 ;
for ( int j = 0 ; j < n1 ; ++ j ) {
ans += dep[a[j]] ;
if ( j ) ans -= dep[lca ( a[j - 1] , a[j] )] ;
}
printf ( "%d\n" , ans ) ;
tot += b[i] ;
}
}
int main () {
int T ;
scanf ( "%d" , &T ) ;
for ( int i = 1 ; i <= T ; ++ i ) {
printf ( "Case #%d:\n" , i ) ;
solve () ;
}
return 0 ;
}