HDU 5877 dfs+ 线段树(或+树状树组)
2、总结:有多种做法,这里写了dfs+线段树(或+树状树组),还可用主席树或平衡树,但还不会这两个
3、思路:利用dfs遍历子节点,同时对于每个子节点au,查询它有多少个祖先av满足av<=k/au。
(1)dfs+线段树
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
#include<cstdio>
#define F(i,a,b) for (int i=a;i<b;i++)
#define FF(i,a,b) for (int i=a;i<=b;i++)
#define mes(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int N=,MAX=; LL k,a[N],b[N*];
int n,m,tree[N*],head[N],in[N]; //注:N*8,不是N*4,因为m可能会是n的2倍 struct Edge
{
int to,nexte;
}edge[N*]; int tot;
void AddEdge(int u,int v)
{
edge[tot].to=v;
edge[tot].nexte=head[u];
head[u]=tot++;
} void update(int pos,int l,int r,int ro,int val)
{
if(l==r){
tree[ro]+=val;
return ;
}
int mid=(l+r)>>;
if(pos<=mid)update(pos,l,mid,ro<<,val);
else update(pos,mid+,r,ro<<|,val);
tree[ro]=tree[ro<<]+tree[ro<<|];
} int query(int R,int l,int r,int ro,int L)
{
if(R>=r&&l>=L){ //注:返回条件
return tree[ro];
}
int mid=(l+r)>>;
if(R<=mid)return query(R,l,mid,ro<<,L);
else if(L>mid)return query(R,mid+,r,ro<<|,L);
else return query(mid,l,mid,ro<<,L)+query(R,mid+,r,ro<<|,mid+); //注:要拆分区间
} LL ans;
void dfs(int r)
{
int pos=lower_bound(b+,b++m,a[r])-b; //注:lower_bound(), -b不是-(b+1)
int posk=lower_bound(b+,b++m,k/a[r])-b;
ans+=1ll*query(posk,,m,,);
update(pos,,m,,);
for(int i=head[r];i!=-;i=edge[i].nexte){
dfs(edge[i].to); //利用dfs序遍历子孙
}
update(pos,,m,,-);
} int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%I64d",&n,&k);
FF(i,,n){
scanf("%I64d",&a[i]);
b[i]=a[i];
}
m=n;
FF(i,,n) b[++m]=k/a[i];
sort(b+,b++m); //排序,离散基础
m=unique(b+,b++m)-(b+); //注:unique(), -(b+1)不是-b mes(head,-);
int u,v;
mes(in,);
ans=tot=;
FF(i,,n-){
scanf("%d%d",&u,&v);
AddEdge(u,v);
in[v]++;
}
mes(tree,);
FF(i,,n){
if(!in[i]){
dfs(i);break;
}
}
printf("%I64d\n",ans);
} return ;
}
(2)dfs+树状树组
这个刚学,还不太懂
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
#include<cstdio>
#define F(i,a,b) for (int i=a;i<b;i++)
#define FF(i,a,b) for (int i=a;i<=b;i++)
#define mes(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int N=,MAX=; LL k,a[N],b[N*],c[N*];
int n,m,head[N],in[N]; struct Edge
{
int to,nexte;
}edge[N*]; int tot;
void AddEdge(int u,int v)
{
edge[tot].to=v;
edge[tot].nexte=head[u];
head[u]=tot++;
} int Lowbit(int x)
{
return x&(-x);
} void update(int pos,int val)
{
for(int i=pos;i<=m;i+=Lowbit(i)){ //注
c[i]+=val;
}
} LL Sum(int posk)
{
LL ans=;
for(int i=posk;i>;i-=Lowbit(i)){ //注
ans+=c[i];
}
return ans;
} LL ans;
void dfs(int r)
{
int pos=lower_bound(b+,b++m,a[r])-b;
int posk=upper_bound(b+,b++m,k/a[r])-(b+); //注:upper_bound(),-(b+1)不是-b
ans+=Sum(posk);
update(pos,);
for(int i=head[r];i!=-;i=edge[i].nexte){
dfs(edge[i].to);
}
update(pos,-);
} int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%I64d",&n,&k);
FF(i,,n){
scanf("%I64d",&a[i]);
b[i]=a[i];
}
m=n;
FF(i,,n) b[++m]=k/a[i];
sort(b+,b++m);
m=unique(b+,b++m)-(b+); mes(head,-);
mes(c,);
int u,v;
mes(in,);
ans=tot=;
FF(i,,n-){
scanf("%d%d",&u,&v);
AddEdge(u,v);
in[v]++;
}
FF(i,,n){
if(!in[i]){
dfs(i);break;
}
}
printf("%I64d\n",ans);
} return ;
}
HDU 5877 dfs+ 线段树(或+树状树组)的更多相关文章
- HDU 5877 [dfs序][线段树][序]
/* 题意: n个点的树,每个点给定一个权值,给定一个k,求任意一点的子树中,权值小于k/该点权值的点共有多少个. 思路: 1.很明显的子树的操作,应用dfs序. 2.比赛的时候傻逼了,一直在调划分树 ...
- HDU 5877 2016大连网络赛 Weak Pair(树状数组,线段树,动态开点,启发式合并,可持久化线段树)
Weak Pair Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Tota ...
- hdu 5877 (dfs+树状数组) Weak Pair
题目:这里 题意: 给出一个n个结点的树和一个数k,每个结点都有一个权值,问有多少对点(u,v)满足u是v的祖先结点且二者的权值之积小于等于k. 从根结点开始dfs,假设搜的的点的权值是v,我们需要的 ...
- hdu 5692(dfs+线段树) Snacks
题目http://acm.hdu.edu.cn/showproblem.php?pid=5692 题目说每个点至多经过一次,那么就是只能一条路线走到底的意思,看到这题的格式, 多个询问多个更新, 自然 ...
- HDU 5877 Weak Pair(树状数组+dfs+离散化)
http://acm.hdu.edu.cn/showproblem.php?pid=5877 题意: 给出一棵树,每个顶点都有权值,现在要你找出满足要求的点对(u,v)数,u是v的祖先并且a[u]*a ...
- R - Weak Pair HDU - 5877 离散化+权值线段树+dfs序 区间种类数
R - Weak Pair HDU - 5877 离散化+权值线段树 这个题目的初步想法,首先用dfs序建一颗树,然后判断对于每一个节点进行遍历,判断他的子节点和他相乘是不是小于等于k, 这么暴力的算 ...
- 树形DP+树状数组 HDU 5877 Weak Pair
//树形DP+树状数组 HDU 5877 Weak Pair // 思路:用树状数组每次加k/a[i],每个节点ans+=Sum(a[i]) 表示每次加大于等于a[i]的值 // 这道题要离散化 #i ...
- hdu 5877 线段树(2016 ACM/ICPC Asia Regional Dalian Online)
Weak Pair Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total ...
- Snacks HDU 5692 dfs序列+线段树
Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...
随机推荐
- h5 range应用 透明度+RGB
透明度 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...
- uC/OS II原理分析及源码阅读(一)
uC/OS II(Micro Control Operation System Two)是一个可以基于ROM运行的.可裁减的.抢占式.实时多任务内核,具有高度可移植性,特别适合于微处理器和控制器,是和 ...
- 提高Axure设计效率的10条建议 (转)
Axure 是创建软件原型的快速有力的工具.上手很容易,但是,其中存在一个危险.这款软件是如此的直观以至于很多用户可以在没有接受过任何正式培训的情况下进行使用.他们可能不知道的是他们可能没有以恰当的方 ...
- Android之TabHost布局(转)
1.概念 盛放Tab的容器就是TabHost.TabHost的实现有两种方式: 第一种继承TabActivity,从TabActivity中用getTabHost()方法获取TabHost.各个Tab ...
- Windows服务定时执行任务
1.创建多线程类 /// <summary> /// 多线程 /// </summary> public abstract class MuliThread<T> ...
- Liferay 6.2 改造系列之五:修改默认站点的页面内容
相关页面可以通过/portal-master/portal-impl/src/portal.properties文件配置进行修改: 登录页: ## ## Default Landing Page ## ...
- 那些Android中的性能优化
性能优化是一个大的范畴,如果有人问你在Android中如何做性能优化的,也许都不知道从哪开始说起. 首先要明白的是,为什么我们的App需要优化,最显而易见的时刻:用户say,什么狗屎,刷这么久都没反应 ...
- AngularJS 学习之事件
1.ng-click指令:定义了AngularJS点击事件 <div ng-app="" ng-controller="myCtrl"> <b ...
- PHP 设置代码执行时间
<?php ini_set('max_execution_time', '0'); set_time_limit(0); ?>
- js-DOM,DOM扩展
DOM: 1. 了解节点的信息:nodeName(属性的标签名),nodeValue两个属性 在取得信息之前要进行判断是不是节点,节点类型由12个数值常量进行表示 2.每个节点都有一个childNod ...