BZOJ4756 - [Usaco2017 Jan]Promotion Counting

2024-03-19 17:58

本文主要是介绍BZOJ4756 - [Usaco2017 Jan]Promotion Counting,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Portal

Description

给出一个\(n(n\leq10^5)\)个点的带点权的以\(1\)为根的树,求每个点的子树中有多少个权值比该点大的点。

Solution

线段树合并。
我们对于每一个点\(u\),建立一棵线段树保存子树\(u\)中的所有权值。那么\(ans_u\)就等于线段树中比\(val_u\)大的值有多少。而子树\(u\)中的所有权值等于\(u\)的所有子节点的子树中的权值加上\(val_u\),那么想要构建出\(u\)的线段树,只要将\(son_u\)的线段树全部合并起来再加上\(val_u\)就好啦。注意以上所说的线段树都是要动态开点的。
如何合并两棵线段树呢?我们递归的去合并线段树中的每一个位置。merge(p1,p2)返回合并节点\(p_1\)\(p_2\)之后得到的节点,看代码就很容易理解啦。

时间复杂度\(O(nlogn)\)

Code

//[Usaco2017 Jan]Promotion Counting
#include <algorithm>
#include <cstdio>
using namespace std;
inline char gc()
{static char now[1<<16],*s,*t;if(s==t) {t=(s=now)+fread(now,1,1<<16,stdin); if(s==t) return EOF;}return *s++;
}
inline int read()
{int x=0; char ch=gc();while(ch<'0'||'9'<ch) ch=gc();while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();return x;
}
const int N=1e5+10;
int n,val[N]; int ans[N];
int n0,map[N];
void discrete()
{for(int i=1;i<=n;i++) map[i]=val[i];sort(map+1,map+n+1); n0=unique(map+1,map+n+1)-map-1;for(int i=1;i<=n;i++) val[i]=lower_bound(map+1,map+n0+1,val[i])-map;n0++; //有可能会询问max+1
}
int cnt,h[N];
struct edge{int v,nxt;} ed[N];
void edAdd(int u,int v) {cnt++; ed[cnt].v=v,ed[cnt].nxt=h[u],h[u]=cnt;}
const int Ns=3e6+10;
int sgCnt,rt[N],ch[Ns][2],sum[Ns];
void update(int p) {sum[p]=sum[ch[p][0]]+sum[ch[p][1]];}
void ins(int &p,int L0,int R0,int x)
{if(!p) p=++sgCnt;if(x<=L0&&R0<=x) {sum[p]++; return;}if(!p) p=++sgCnt;int mid=L0+R0>>1;if(x<=mid) ins(ch[p][0],L0,mid,x);else ins(ch[p][1],mid+1,R0,x);update(p);
}
int query(int &p,int L0,int R0,int L)
{if(!p) p=++sgCnt;if(L<=L0) return sum[p];int mid=L0+R0>>1; int res=0;if(L<=mid) res+=query(ch[p][0],L0,mid,L);res+=query(ch[p][1],mid+1,R0,L);return res; 
}
int merge(int p1,int p2)
{if(!p1||!p2) return !p1?p2:p1;ch[p1][0]=merge(ch[p1][0],ch[p2][0]);ch[p1][1]=merge(ch[p1][1],ch[p2][1]);sum[p1]+=sum[p2];return p1;
}
void dfs(int u)
{ins(rt[u],1,n0,val[u]);for(int i=h[u];i;i=ed[i].nxt){int v=ed[i].v;dfs(v); rt[u]=merge(rt[u],rt[v]);}ans[u]=query(rt[u],1,n0,val[u]+1);
}
int main()
{n=read();for(int i=1;i<=n;i++) val[i]=read();discrete();for(int i=2;i<=n;i++) edAdd(read(),i);dfs(1);for(int i=1;i<=n;i++) printf("%d\n",ans[i]);return 0;
} 

P.S.

Icefox的树状数组解法不知比我高到哪里去了
太懒断更了几天...

转载于:https://www.cnblogs.com/VisJiao/p/BZOJ4756.html

这篇关于BZOJ4756 - [Usaco2017 Jan]Promotion Counting的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/826811

相关文章

POJ 2386 Lake Counting(DFS)

题目: http://poj.org/problem?id=2386 题解: 遍历一次,遇到w,一次DFS后,与此w连接的所有w都被替换成‘ . ’,直到遍历完图中不再存在w为止,总共进行DFS的次数就是答案了。 代码: #include<stdio.h>int N,M;char map[110][110];void dfs(int x,int y){map[x][y]='

[LeetCode] 338. Counting Bits

题:https://leetcode.com/problems/counting-bits/description/ 题目 Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1’s in their binary repres

《Zero-Shot Object Counting》CVPR2023

摘要 论文提出了一种新的计数设置,称为零样本对象计数(Zero-Shot Object Counting, ZSC),旨在测试时对任意类别的对象实例进行计数,而只需在测试时提供类别名称。现有的类无关计数方法需要人类标注的示例作为输入,这在许多实际应用中是不切实际的。ZSC方法不依赖于人类标注者,可以自动操作。研究者们提出了一种方法,可以从类别名称开始,准确识别出最佳的图像块(patches),用

Swift 3.0 学习 -- 计算字符数量 (Counting Characters)

在swift2.0的时候,可以通过调用全局countElements函数,并将字符串作为参数进行传递,可以获取该字符串的字符数量。如下: let unusualMenagerie = "Koala, Snail, Penguin, Dromedary"print("unusualMenagerie has \(countElements(unusualMenagerie)) charact

leetcode338 Counting Bits Java

Description Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1’s in their binary representation and return them as an array. Example: Fo

UVA 11401 Triangle Counting

中文详解请访问我的博客:http://xiaoshig.sinaapp.com/?p=128 You are given n rods of length 1, 2…, n. You have to pick any 3 of them & build a triangle. How many distinct triangles can you make? Note that, two

sdut2610--Boring Counting(二分+划分树)

Boring Counting Time Limit: 3000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述     In this problem you are given a number sequence P consisting of N integer and Pi is the ith element in the

论文笔记 A Large Contextual Dataset for Classification,Detection and Counting of Cars with Deep Learning

ECCV 2016的文章,首先建立了一个从上到下照的车辆影像数据集(即鸟瞰视角),并提出ResCeption神经网络进行训练,进一步建立residual learning with Inception-style layers,进行车辆数目的计算。该方法为车辆数目的计算的一种新方式:通过定位和密度估计方法。对于新的场景或新的目标计数也同样适用。 文章主要关注3个任务点:(1)两类的分类问题(2)

338. Counting Bits 比特位计数

https://leetcode-cn.com/problems/counting-bits/description/ Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1’s in their binary represent

计数排序(Counting Sort)

计数排序(Counting Sort) 计数排序是一个非基于比较的排序算法,该算法于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,快于任何比较排序算法。排序思路: 1.找出待排序数组最大值2.定义一个索引最大值为待排序数组最大值的数组3.遍历待排序数组, 将待排序数组遍历到的值作新数组索引4.在新数组对应索引存储值原有基础上+1 简单代码实现