hdu 4605
给出一棵二叉树,每个点具有权值,给出q次查询,每次查询给出一个X,找到到达点v的概率(表示为 7x/2y ),行走规则为,若X>w[u],那么走到左孩子和右孩子的概率分别是1/2,X
树状数组实现:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#define MAX 100007
using namespace std;
int t,n,m,q;
int w[MAX];
vector<int> e[MAX];
int ans[MAX][2];
int lef[MAX<<1];
int rig[MAX<<1];
int num[MAX],cnum;
void addEdge ( int u , int v )
{
e[u].push_back ( v );
}
struct Query
{
int id,x,v;
}temp;
vector<Query> a[MAX];
int lowbit ( int x )
{
return x&-x;
}
void Clear ( )
{
for ( int i = 0 ; i < MAX ; i++ )
{
e[i].clear();
a[i].clear();
}
memset ( lef , 0 , sizeof ( lef ) );
memset ( rig , 0 , sizeof ( rig ) );
cnum = 1;
}
void add ( int c[] , int x , int v )
{
while ( x < cnum )
{
c[x] += v;
x += lowbit ( x );
}
}
int sum ( int c[] , int x )
{
int ret = 0;
while ( x )
{
ret += c[x];
x -= lowbit ( x );
}
return ret;
}
int bsearch ( int x )
{
int l=1,r=cnum,mid;
while ( l != r )
{
mid = l+r>>1;
if ( num[mid] == x ) return mid;
if ( num[mid] < x ) l = mid+1;
else r= mid;
}
return mid;
}
void dfs ( int u )
{
for ( int i = 0 ; i < a[u].size(); i++ )
{
int id = a[u][i].id;
int x = bsearch ( a[u][i].x );
if ( sum ( lef , x )- sum ( lef , x-1 ) + sum(rig , x ) - sum ( rig , x-1 ) > 0 )
{
ans[id][0] = -1;
continue;
}
int ll = sum ( lef , x-1 );
int lr = sum ( lef , cnum-1 ) - sum ( lef , x );
int rl = sum ( rig , x-1 );
int rr = sum ( rig , cnum-1 ) - sum ( rig , x );
ans[id][0] = rl;
ans[id][1] = (rl+ll)*3 + rr + lr;
}
int x = bsearch ( w[u] );
if ( e[u].size() == 0 ) return;
int v = e[u][0];
if ( v != -1 )
{
add ( lef , x , 1 );
dfs ( v );
add ( lef , x , -1 );
}
v = e[u][1];
if ( v != -1 )
{
add ( rig , x , 1 );
dfs ( v );
add ( rig , x , -1 );
}
}
int main ( )
{
scanf ( "%d" , &t );
while ( t-- )
{
Clear();
scanf ( "%d" , &n );
for ( int i = 1 ; i <= n ; i++ )
{
scanf ( "%d" , &w[i] );
num[cnum++] = w[i];
}
scanf ( "%d" , &m );
int u,x,y;
for ( int i = 0 ; i < m ; i++ )
{
scanf ( "%d%d%d" , &u , &x , &y );
addEdge ( u , x );
addEdge ( u , y );
}
scanf ( "%d" , &q );
for ( int i = 0 ; i < q ; i++ )
{
scanf ( "%d%d" , &temp.v , &temp.x );
temp.id = i;
a[temp.v].push_back ( temp );
num[cnum++] = temp.x;
}
sort ( num+1 , num+cnum );
cnum = unique ( num+1 , num+cnum )-num;
dfs ( 1 );
for ( int i = 0 ; i < q ; i++ )
{
if ( ans[i][0] == -1 )
puts ( "0" );
else
printf ( "%d %d\n" , ans[i][0] , ans[i][1] );
}
}
return 0;
}
主席树实现:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#define MAX 100007
using namespace std;
int t,n,m,q;
int w[MAX];
vector<int> e[MAX];
int ans[MAX][2];
int lef[MAX<<1];
int rig[MAX<<1];
int num[MAX],cnum;
void addEdge ( int u , int v )
{
e[u].push_back ( v );
}
struct Query
{
int id,x,v;
}temp;
vector<Query> a[MAX];
int lowbit ( int x )
{
return x&-x;
}
void Clear ( )
{
for ( int i = 0 ; i < MAX ; i++ )
{
e[i].clear();
a[i].clear();
}
memset ( lef , 0 , sizeof ( lef ) );
memset ( rig , 0 , sizeof ( rig ) );
cnum = 1;
}
void add ( int c[] , int x , int v )
{
while ( x < cnum )
{
c[x] += v;
x += lowbit ( x );
}
}
int sum ( int c[] , int x )
{
int ret = 0;
while ( x )
{
ret += c[x];
x -= lowbit ( x );
}
return ret;
}
int bsearch ( int x )
{
int l=1,r=cnum,mid;
while ( l != r )
{
mid = l+r>>1;
if ( num[mid] == x ) return mid;
if ( num[mid] < x ) l = mid+1;
else r= mid;
}
return mid;
}
void dfs ( int u )
{
for ( int i = 0 ; i < a[u].size(); i++ )
{
int id = a[u][i].id;
int x = bsearch ( a[u][i].x );
if ( sum ( lef , x )- sum ( lef , x-1 ) + sum(rig , x ) - sum ( rig , x-1 ) > 0 )
{
ans[id][0] = -1;
continue;
}
int ll = sum ( lef , x-1 );
int lr = sum ( lef , cnum-1 ) - sum ( lef , x );
int rl = sum ( rig , x-1 );
int rr = sum ( rig , cnum-1 ) - sum ( rig , x );
ans[id][0] = rl;
ans[id][1] = (rl+ll)*3 + rr + lr;
}
int x = bsearch ( w[u] );
if ( e[u].size() == 0 ) return;
int v = e[u][0];
if ( v != -1 )
{
add ( lef , x , 1 );
dfs ( v );
add ( lef , x , -1 );
}
v = e[u][1];
if ( v != -1 )
{
add ( rig , x , 1 );
dfs ( v );
add ( rig , x , -1 );
}
}
int main ( )
{
scanf ( "%d" , &t );
while ( t-- )
{
Clear();
scanf ( "%d" , &n );
for ( int i = 1 ; i <= n ; i++ )
{
scanf ( "%d" , &w[i] );
num[cnum++] = w[i];
}
scanf ( "%d" , &m );
int u,x,y;
for ( int i = 0 ; i < m ; i++ )
{
scanf ( "%d%d%d" , &u , &x , &y );
addEdge ( u , x );
addEdge ( u , y );
}
scanf ( "%d" , &q );
for ( int i = 0 ; i < q ; i++ )
{
scanf ( "%d%d" , &temp.v , &temp.x );
temp.id = i;
a[temp.v].push_back ( temp );
num[cnum++] = temp.x;
}
sort ( num+1 , num+cnum );
cnum = unique ( num+1 , num+cnum )-num;
dfs ( 1 );
for ( int i = 0 ; i < q ; i++ )
{
if ( ans[i][0] == -1 )
puts ( "0" );
else
printf ( "%d %d\n" , ans[i][0] , ans[i][1] );
}
}
return 0;
}