题解 P3605 【[USACO17JAN]Promotion Counting晋升者计数】
这道题开10倍左右一直MLE+RE,然后尝试着开了20倍就A了。。。窒息
对于这道题目,我们考虑使用线段树合并来做。
所谓线段树合并,就是把结构相同的线段树上的节点的信息合在一起,合并的方式比较类似左偏树什么的。
我们对于每个节点用权值线段树查询大于它的子节点数量,然后把当前节点并到它的父亲上面去。
对于此类型的题目我们通常使用动态开点的线段树(不然炸的没边)。
时间复杂度应该是$O(nlogn)$
AC代码如下:
455ms 32824kb
#include <bits/stdc++.h>
using namespace std;
namespace StandardIO {
template<typename T> inline void read (T &x) {
x=;T f=;char c=getchar();
for(; c<''||c>''; c=getchar()) if(c=='-') f=-;
for(; c>=''&&c<=''; c=getchar()) x=x*+c-'';
x*=f;
}
template<typename T>inline void write (T x) {
if (x<) putchar('-'),x*=-;
if (x>=) write(x/);
putchar(x%+'');
}
}
using namespace StandardIO;
namespace Solve {
const int N=;
int n;
int cnt;
struct node {
int id,v;
inline bool operator < (const node &x) const {
return v<x.v;
}
}p[N];
vector<int>graph[N];
int tree_node;
int val[N],tree[(int)(N*)],ls[(int)(N*)],rs[(int)(N*)],root[N],ans[N];
void build (int l,int r,int v,int &root) {
if (!root) root=++tree_node;
tree[root]++;
if (l==r) return;
int mid=(l+r)>>;
if (v<=mid) build(l,mid,v,ls[root]);
else build(mid+,r,v,rs[root]);
}
int query (int l,int r,int v,int root) {
if (!root) return ;
if (v<=l) return tree[root];
int mid=(l+r)>>;
if (v<=mid) return query(l,mid,v,ls[root])+query(mid+,r,v,rs[root]);
return query(mid+,r,v,rs[root]);
}
int merge (int x,int y) {
if (!x||!y) return x+y;
int root=++tree_node;
tree[root]=tree[x]+tree[y];
ls[root]=merge(ls[x],ls[y]);
rs[root]=merge(rs[x],rs[y]);
return root;
}
void dfs (int now) {
for (register int i=; i<graph[now].size(); ++i) {
int to=graph[now][i];
dfs(to);
root[now]=merge(root[now],root[to]);
}
ans[now]=query(,cnt,val[now]+,root[now]);
build(,cnt,val[now],root[now]);
}
inline void solve () {
read(n);
for (register int i=; i<=n; ++i) {
read(p[i].v),p[i].id=i;
}
sort(p+,p+n+);
for (register int i=; i<=n; ++i) {
if (p[i].v!=p[i-].v) val[p[i].id]=++cnt;
else val[p[i].id]=cnt;
}
for (register int i=; i<=n; ++i) {
int x;read(x);
graph[x].push_back(i);
}
dfs();
for (register int i=; i<=n; ++i) {
write(ans[i]),putchar('\n');
}
}
}
using namespace Solve;
int main () {
solve();
}
题解 P3605 【[USACO17JAN]Promotion Counting晋升者计数】的更多相关文章
- 线段树合并 || 树状数组 || 离散化 || BZOJ 4756: [Usaco2017 Jan]Promotion Counting || Luogu P3605 [USACO17JAN]Promotion Counting晋升者计数
题面:P3605 [USACO17JAN]Promotion Counting晋升者计数 题解:这是一道万能题,树状数组 || 主席树 || 线段树合并 || 莫队套分块 || 线段树 都可以写..记 ...
- 树状数组 P3605 [USACO17JAN]Promotion Counting晋升者计数
P3605 [USACO17JAN]Promotion Counting晋升者计数 题目描述 奶牛们又一次试图创建一家创业公司,还是没有从过去的经验中吸取教训--牛是可怕的管理者! 为了方便,把奶牛从 ...
- 洛谷P3605 [USACO17JAN] Promotion Counting 晋升者计数 [线段树合并]
题目传送门 Promotion Counting 题目描述 The cows have once again tried to form a startup company, failing to r ...
- 洛谷 P3605 [USACO17JAN]Promotion Counting晋升者计数
题目描述 The cows have once again tried to form a startup company, failing to remember from past experie ...
- luogu P3605 [USACO17JAN]Promotion Counting晋升者计数
题目链接 luogu 思路 可以说是线段树合并的练手题目吧 也没啥说的,就是dfs,然后合并... 看代码吧 错误 和写主席树错的差不多 都是变量写错.... 代码 #include <bits ...
- P3605 [USACO17JAN]Promotion Counting晋升者计数
思路 线段树合并的板子.. 和子节点合并之后在值域线段树上查询即可 代码 #include <cstdio> #include <algorithm> #include < ...
- Luogu3605 [USACO17JAN]Promotion Counting晋升者计数
Luogu3605 [USACO17JAN]Promotion Counting晋升者计数 给一棵 \(n\) 个点的树,点 \(i\) 有一个权值 \(a_i\) .对于每个 \(i\) ,求 \( ...
- [USACO17JAN]Promotion Counting晋升者计数
题目描述 奶牛们又一次试图创建一家创业公司,还是没有从过去的经验中吸取教训--牛是可怕的管理者! 为了方便,把奶牛从 1 \cdots N(1 \leq N \leq 100, 000)1⋯N(1≤N ...
- 题解 P3605 [USACO17JAN]Promotion Counting P
分块\(yyds\) ----关于线段树合并的题我用分块过掉这件事 题目传送门 先说正解 正解当然是线段树合并等一类做法了 至于解析...出门右转题解区第一篇 (就是他让我看不懂,然后用分块打的\(Q ...
随机推荐
- (转载)Android:学习AIDL,这一篇文章就够了(下)
前言 上一篇博文介绍了关于AIDL是什么,为什么我们需要AIDL,AIDL的语法以及如何使用AIDL等方面的知识,这一篇博文将顺着上一篇的思路往下走,接着介绍关于AIDL的一些更加深入的知识.强烈建议 ...
- html5plus 从相册选择图片后获取图片的大小
plus.gallery.pick(function (filePath) { plus.io.resolveLocalFileSystemURL(filePath, function (entry) ...
- 3ds Max制作客厅场景实例教程
附件系列 (图01) 让我们回顾一下场景:一个房间包括下列一件件家具, 在中间的一张小桌子,在房间的角落的一个小桌子,有一个垃圾桶和一个带镜子的边桌,有一个烛台.还有一个挂钟,窗帘,沙发和带手臂的椅子 ...
- Linux grep 筛选语句
1. 同时满足多个条件 cat logs.log |grep 123|grep 'abc'|more --查询logs.log中同时满足123和abc的句子 2. 满足任意一个条件 cat ...
- 织梦(dedecms)循环调用多级子栏目如二级栏目下三级栏目
本文是关于织梦DedeCMS调用多级子栏目的,拿来分享下. 后台已经建好栏目,对于产品展示栏 栏目导航如下图所示: 复制代码 代码如下: {dede:channelartlist cacheid=' ...
- js验证输入框
项目开发中,都会有对表单form中的input输入框进行一些限制验证 如: <!DOCTYPE html><html lang="en"> <head ...
- 【jQuery05】通过按键 来切换 class
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 详解:(cron , crontab , anacron)
导读: 人类把时间做了切割,想象一条笔直的线永远向前,本来这条直线上什么都没有,但是人类根据时间的长短(单位)在这条直线上做了密密麻麻的标记(世纪-年-月-日-时-分-秒-纳秒......),通过这样 ...
- 每个人都能实现的vue自定义指令
前文 先来bb一堆废话哈哈.. 用vue做项目也有一年多了.除了用别人的插件之外.自己也没尝试去封装指令插件之类的东西来用. 刚好最近在项目中遇到一个问题.(快速点击按钮多次触发多次绑定的方法),于是 ...
- 紫书 例题8-19 UVa 12265 (扫描法+单调栈)
首先可以用扫描法处理出一个height数组, 来保存从当前行开始, 每一个格子可以向上延伸的最大长度. 这种"延伸"的问题用扫描法, 因为往往这个时候可以利用前一次的结果来更新当前 ...