【COGS】1535 [ZJOI2004]树的果实 树状数组
来源:互联网 发布:卓越绩效管理体系软件 编辑:程序博客网 时间:2024/05/01 07:48
传送门:【COGS】1535 [ZJOI2004]树的果实
题目分析:遇到和树有关的肯定先dfs,首先将美味值离散化(反正所有的都不相同,随便离散),然后按照题目给的树dfs,顺便记录其时间戳用以求前两个答案,因为dfs走的恰好是从根到一个点的路径,所以在dfs是顺带用树状数组维护果实的个数,答案三就是查询前面添加的果实有多少比当前的大就行了。
接下来把果实按照美味值从大到小排序(其实还是同一个比较函数,到过来读取就行了),每次为这个果实 u 查找子树区间[ in[ u ] , ou[ u ] ]内有多少比他大就好了,这个是答案一,然后答案二就等于n - fruit[ u ].x(x为离散后的)-答案一。
是不是很简单?就是我写的比较搓,跑的很慢。
代码如下:
#include <cmath>#include <cstdio>#include <cstring>#include <algorithm>using namespace std ;#define REP( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i )#define FOR( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i )#define REV( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i )#define travel( e , H , u ) for ( Edge* e = H[u] ; e ; e = e -> next )#define CLR( a , x ) memset ( a , x , sizeof a )#define CPY( a , x ) memcpy ( a , x , sizeof a )#define ls ( o << 1 )#define rs ( o << 1 | 1 )#define lson ls , l , m#define rson rs , m + 1 , r#define mid ( ( l + r ) >> 1 )#define root 1 , 1 , n#define rt o , l , rconst int MAXN = 100005 ;const int MAXE = 100005 ;struct Edge {int v ;Edge* next ;} E[MAXE] , *H[MAXN] , *cur ;struct Node {int x , idx ;} fruit[MAXN] ;int in[MAXN] , ou[MAXN] , dfs_clock ;int ans1[MAXN] , ans2[MAXN] , ans3[MAXN] ;int T[MAXN] ;int n ;int cmp1 ( const Node& a , const Node& b ) {return a.x < b.x ;}int cmp2 ( const Node& a , const Node& b ) {return a.idx < b.idx ;}void add ( int x , int v ) {while ( x ) {T[x] += v ;x -= x & -x ;}}int sum ( int x , int ans = 0 ) {if ( !x ) return 0 ;while ( x <= n ) {ans += T[x] ;x += x & -x ;}return ans ;}void clear () {cur = E ;dfs_clock = 0 ;CLR ( H , 0 ) ;CLR ( T , 0 ) ;}void addedge ( int u , int v ) {cur -> v = v ;cur -> next = H[u] ;H[u] = cur ++ ;}void dfs ( int u ) {in[u] = ++ dfs_clock ;ans3[u] = sum ( fruit[u].x ) ;add ( fruit[u].x , 1 ) ;travel ( e , H , u ) dfs ( e -> v ) ;add ( fruit[u].x , -1 ) ;ou[u] = dfs_clock ;}void solve () {int x ;clear () ;scanf ( "%d" , &n ) ;FOR ( i , 2 , n ) {scanf ( "%d" , &x ) ;addedge ( x , i ) ;}FOR ( i , 1 , n ) {scanf ( "%d" , &fruit[i].x ) ;fruit[i].idx = i ;}sort ( fruit + 1 , fruit + n + 1 , cmp1 ) ;FOR ( i , 1 , n ) fruit[i].x = i ;sort ( fruit + 1 , fruit + n + 1 , cmp2 ) ;dfs ( 1 ) ;sort ( fruit + 1 , fruit + n + 1 , cmp1 ) ;CLR ( T , 0 ) ;REV ( i , n , 1 ) {int idx = fruit[i].idx ;//printf ( "%d %d\n" , ou[idx] , in[idx] - 1 ) ;ans1[idx] = sum ( in[idx] ) - sum ( ou[idx] + 1 ) ;ans2[idx] = n - fruit[i].x - ans1[idx] ;add ( in[idx] , 1 ) ;}FOR ( i , 1 , n ) printf ( "%d %d %d\n" , ans1[i] , ans2[i] , ans3[i] ) ;}int main () {freopen ( "treesfruits.in" , "r" , stdin ) ;freopen ( "treesfruits.out" , "w" , stdout ) ;solve () ;}
0 0
- 【COGS】1535 [ZJOI2004]树的果实 树状数组
- [ZJOI2004]树的果实
- 【COGS】421 [SDOI2009] HH的项链 树状数组
- 【COGS】950 切割矩形 线段树&树状数组
- COGS-257-动态排名系统-树状数组+主席树
- COGS-2275 [HEOI 2016] seq(树状数组+线段树)
- COGS 577 蝗灾 cdq分治+树状数组
- Cogs 1008. 贪婪大陆(树状数组)
- SDOI 2009 (COGS 421)HH的项链 分块or树状数组
- 【COGS】257 动态排名系统 【动态第K小】树状数组+主席树
- COGS-1715 [CQOI2011]动态逆序对(树状数组+线段树)
- COGS 2479. [HZOI 2016]偏序 双重CDQ分治+树状数组
- 【COGS】数列操作a,b,c 树状数组练习
- cogs 1752 [BOI2007]摩基亚Mokia(cdq分治+树状数组)
- COGS-2282 [HZOI 2015]黑树白(树状数组+树链剖分)
- 沙漠中没有果实的树
- 盛夏的果实
- 胜利的果实
- shell学习之&& 与 || 差在哪?
- js 正则表达示验证特殊字符
- Shiro 的应用
- “Undefined reference to” 的处理
- c++ STL 代码练习
- 【COGS】1535 [ZJOI2004]树的果实 树状数组
- Linux内核学习2:内核模块的开发
- httpClient采集到的数据乱码问题完整解决
- Unity 3D需要注意的程序基础
- 文本文件与二进制文件区别
- sring mybatis 注解应用
- linux Framebuffer 调试
- OpenCV学习之Condensation算法
- c程序组织