这道题开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晋升者计数】的更多相关文章

  1. 线段树合并 || 树状数组 || 离散化 || BZOJ 4756: [Usaco2017 Jan]Promotion Counting || Luogu P3605 [USACO17JAN]Promotion Counting晋升者计数

    题面:P3605 [USACO17JAN]Promotion Counting晋升者计数 题解:这是一道万能题,树状数组 || 主席树 || 线段树合并 || 莫队套分块 || 线段树 都可以写..记 ...

  2. 树状数组 P3605 [USACO17JAN]Promotion Counting晋升者计数

    P3605 [USACO17JAN]Promotion Counting晋升者计数 题目描述 奶牛们又一次试图创建一家创业公司,还是没有从过去的经验中吸取教训--牛是可怕的管理者! 为了方便,把奶牛从 ...

  3. 洛谷P3605 [USACO17JAN] Promotion Counting 晋升者计数 [线段树合并]

    题目传送门 Promotion Counting 题目描述 The cows have once again tried to form a startup company, failing to r ...

  4. 洛谷 P3605 [USACO17JAN]Promotion Counting晋升者计数

    题目描述 The cows have once again tried to form a startup company, failing to remember from past experie ...

  5. luogu P3605 [USACO17JAN]Promotion Counting晋升者计数

    题目链接 luogu 思路 可以说是线段树合并的练手题目吧 也没啥说的,就是dfs,然后合并... 看代码吧 错误 和写主席树错的差不多 都是变量写错.... 代码 #include <bits ...

  6. P3605 [USACO17JAN]Promotion Counting晋升者计数

    思路 线段树合并的板子.. 和子节点合并之后在值域线段树上查询即可 代码 #include <cstdio> #include <algorithm> #include < ...

  7. Luogu3605 [USACO17JAN]Promotion Counting晋升者计数

    Luogu3605 [USACO17JAN]Promotion Counting晋升者计数 给一棵 \(n\) 个点的树,点 \(i\) 有一个权值 \(a_i\) .对于每个 \(i\) ,求 \( ...

  8. [USACO17JAN]Promotion Counting晋升者计数

    题目描述 奶牛们又一次试图创建一家创业公司,还是没有从过去的经验中吸取教训--牛是可怕的管理者! 为了方便,把奶牛从 1 \cdots N(1 \leq N \leq 100, 000)1⋯N(1≤N ...

  9. 题解 P3605 [USACO17JAN]Promotion Counting P

    分块\(yyds\) ----关于线段树合并的题我用分块过掉这件事 题目传送门 先说正解 正解当然是线段树合并等一类做法了 至于解析...出门右转题解区第一篇 (就是他让我看不懂,然后用分块打的\(Q ...

随机推荐

  1. 连类比事-category和extension

    extension看起来很像一个匿名的category,但是extension和有名字的category几乎完全是两个东西. extension在编译期决议,它就是类的一部分,在编译期和头文件里的@i ...

  2. Uncaught TypeError: Cannot read property 'offsetTop' of undefined at VueComponent.handleScroll

    mounted() { window.addEventListener("scroll", this.handleScroll); }, beforeDestroy() { win ...

  3. git远程仓库变更

    查看自己的远程仓库 git remote -v 远程仓库变更 git remote remove origin //移出现有的远程仓库的地址 git remote add origin http:// ...

  4. 多任务-进程之Queue的进程间通信

    1.经过线程和进程的对比,不难的知道,线程和进程有相当大的区别,如全局变量资源不能够共享. 2.在不同的进程间,如何实现通信呢? 需要提及的一个概念就是Queue,它是一个消息队列,下面通过一个例子来 ...

  5. [NOIP2011提高组]Mayan游戏

    题目:洛谷P1312.Vijos P1738.codevs1136. 题目大意:在一个7行5列的棋盘(左下角坐标0,0)上,有一些不同颜色的棋子. 规定某一时刻,连续三个横排或竖列的棋子颜色相同,则它 ...

  6. java 导出百万数据到excel

    @RequestMapping("export") public void write(HttpServletRequest request,HttpServletResponse ...

  7. 安装 glusterfs yum源报错

    yum install glusterfs-server yum 一直报错 把/etc/yum.repos.d 备份 删除了所有文件,从测试机192..168.59.128上同步过来 一直报错 已加载 ...

  8. python list set dict的简单应用示例

    list.count(x):返回指定元素x在列表中出现的次数 set(list):将list类型变量转换为set类型,去除重复值 dick:保存键值对 x=[1,2,2,3,3] s1=set(x) ...

  9. 养活一款APP要“烧”多少钱?

    Duang!又一款APP刷爆朋友圈.大片范儿的电影截图.意味深长的经典对白均出自一款名为“足记”的APP. 足记团队刚于去年8月完成天使期融资,投资方是光速创投和紫辉创投,目前正准备A轮融资.且近一周 ...

  10. win7休眠的开启与关闭方法命令行操作和图文结合的鼠标操作

    win7休眠的开启与关闭方法 从開始菜单中找到"附件→命令提示符",手工输入例如以下命令:powercfg -a.从这里能够清楚的看到,计算机是支持休眠的.显示"尚未启用 ...