博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 4756 [Usaco2017 Jan]Promotion Counting
阅读量:7016 次
发布时间:2019-06-28

本文共 2513 字,大约阅读时间需要 8 分钟。

题目链接

思路

线段树合并,每次搜索,先递归搜索子树,然后合并它与子树代表的线段树,最后查询线段树中大于当前点权值的值的个数,由于是动态开点,不离散化似乎也可以,但是离散化常数可能会小一点。

代码

#include 
#include
const int maxn=100000;const int maxd=2000000;int read(){ int x=0,f=1; char ch=getchar(); while((ch<'0')||(ch>'9')) { if(ch=='-') { f=-f; } ch=getchar(); } while((ch>='0')&&(ch<='9')) { x=x*10+ch-'0'; ch=getchar(); } return x*f;}struct node{ node* son[2]; int sum;};int n,p[maxn+10],cnt_node,tmp[maxn+10],ans[maxn+10];int pre[maxn+10],now[maxn+10],son[maxn+10],tot;node tnode[maxd+10];node* root[maxn+10];int updata(node* now){ now->sum=0; if(now->son[0]!=NULL) { now->sum+=now->son[0]->sum; } if(now->son[1]!=NULL) { now->sum+=now->son[1]->sum; } return 0;}int build(node* now,int l,int r,int v){ if(l==r) { now->sum=1; now->son[0]=now->son[1]=NULL; return 0; } int mid=(l+r)>>1; if(v<=mid) { build(now->son[0]=&tnode[++cnt_node],l,mid,v); now->son[1]=NULL; } else { now->son[0]=NULL; build(now->son[1]=&tnode[++cnt_node],mid+1,r,v); } updata(now); return 0;}node* merge(node* a,node* b,int l,int r){ if(a==NULL) { return b; } if(b==NULL) { return a; } int mid=(l+r)>>1; a->son[0]=merge(a->son[0],b->son[0],l,mid); a->son[1]=merge(a->son[1],b->son[1],mid+1,r); updata(a); return a;}int getsum(node* now,int l,int r,int askl,int askr){ if((askl<=l)&&(r<=askr)) { return now->sum; } int mid=(l+r)>>1,res=0; if((askl<=mid)&&(now->son[0]!=NULL)) { res+=getsum(now->son[0],l,mid,askl,askr); } if((mid
son[1]!=NULL)) { res+=getsum(now->son[1],mid+1,r,askl,askr); } return res;}inline int ins(int a,int b){ pre[++tot]=now[a]; now[a]=tot; son[tot]=b; return 0;}int dfs(int u){ int j=now[u]; while(j) { int v=son[j]; dfs(v); root[u]=merge(root[u],root[v],1,n); j=pre[j]; } ans[u]=getsum(root[u],1,n,p[u]+1,n); return 0;}int main(){ n=read(); for(int i=1; i<=n; ++i) { p[i]=tmp[i]=read(); } std::sort(tmp+1,tmp+n+1); for(int i=1; i<=n; ++i) { p[i]=std::lower_bound(tmp+1,tmp+n+1,p[i])-tmp; } for(int i=1; i<=n; ++i) { build(root[i]=&tnode[++cnt_node],1,n,p[i]); } for(int i=2; i<=n; ++i) { int a=read(); ins(a,i); } dfs(1); for(int i=1; i<=n; ++i) { printf("%d\n",ans[i]); } return 0;}

转载于:https://www.cnblogs.com/Canopus-wym/p/10376182.html

你可能感兴趣的文章
ESXi安装实录
查看>>
Leetcode: Roman to Integer
查看>>
Tomcat 配置加密的服务器连接器
查看>>
jQuery 学习笔记1 弹出一个对话框
查看>>
GCD介绍(二): 多核心的性能
查看>>
Openfire开发配置,Openfire源代码配置,OpenFire二次开发配置
查看>>
转 CentOS开启FTP及配置用户
查看>>
前端文摘:Web 开发模式演变历史和趋势
查看>>
win7的优化-1:隐藏我的电脑导航栏里的收藏等项目
查看>>
Consequence of Point-by-Point Bounds
查看>>
c# 封装的7zip压缩 (全源码,不含任何类库)
查看>>
三、OPENERP 中的对象关系类型
查看>>
PHP-CGI 进程 CPU 100% 与 file_get_contents 函数的关系
查看>>
流行时尚!21例创新的侧边栏菜单网页设计作品
查看>>
android jni编译时Android.mk文件的规范说明
查看>>
paip.enhes efis 自动获取文件的中文编码
查看>>
[物理学与PDEs]书中出现的符号及其意义汇总
查看>>
centos+apache+mod_ssl
查看>>
Python:Hello World级别的SimpleDb
查看>>
C#:列表视图操作类
查看>>