hdu 4605 线段树与二叉树遍历
思路:
首先将所有的查询有一个vector保存起来。我们从1号点开始dfs这颗二叉树,用线段树记录到当前节点时,走左节点的有多少比要查询该节点的X值小的,有多少大的,
同样要记录走右节点的有多少比X小的,多少比X大的。小和大的x,y值题目给了。当要进行左儿子时,建该节点值插入走左的线段树,回退的时候将其删除,进入右儿子时将其插入走右的线段树,同样回退时删除。遍历完一个树,整个查询就做完了,最后输出。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#define Maxn 200100
#define lson(x) (x<<1)
#define rson(x) ((x<<1)+1)
#define mid ((tree[po].l+tree[po].r)>>1)
#define inf 100000000
using namespace std;
struct Query{
int x,i;
};
struct AA{
int x,y;
}ans[Maxn];
struct Tree{
int l,r,lnum,rnum;
}tree[Maxn*];
int head[Maxn],e,w[Maxn],Index[Maxn],flag=,L,R,Lsum,Rsum;
vector<Query> query[Maxn];
struct Edge{
int u,v,next;
}edge[Maxn];
void buildTree(int l,int r,int po)
{
tree[po].l=l,tree[po].r=r;
tree[po].lnum=,tree[po].rnum=;
if(l==r)
return ;
buildTree(l,mid,lson(po));
buildTree(mid+,r,rson(po));
}
void Insert(int val,int po,int type)
{
if(tree[po].l==tree[po].r)
{
if(type)
tree[po].rnum++;
else
tree[po].lnum++;
return ;
}
if(type)
tree[po].rnum++;
else
tree[po].lnum++;
if(Index[mid]>=val)
Insert(val,lson(po),type);
else
Insert(val,rson(po),type);
}
void del(int val,int po,int type)
{
if(tree[po].l==tree[po].r)
{
if(type)
tree[po].rnum--;
else
tree[po].lnum--;
return ;
}
if(type)
tree[po].rnum--;
else
tree[po].lnum--;
if(Index[mid]>=val)
del(val,lson(po),type);
else
del(val,rson(po),type);
}
void get_Num(int val,int po)
{
if(Index[tree[po].l]>val)
return ;
if(Index[tree[po].r]<val)
{
R+=tree[po].rnum;
L+=tree[po].lnum;
return ;
}
if(tree[po].l==tree[po].r)
{
if(tree[po].rnum||tree[po].lnum)//如果图中有相同数值,则不能到达
flag=;
return ;
}
get_Num(val,lson(po));
get_Num(val,rson(po));
}
void init()
{
e=;
Lsum=Rsum=;
memset(head,-,sizeof(head));
for(int i=;i<=;i++)
{
query[i].clear();
ans[i].x=ans[i].y=;
}
}
void add(int u,int v)
{
edge[e].u=u;edge[e].v=v;edge[e].next=head[u];head[u]=e++;
}
void dfs(int u)//进行二叉树遍历
{
int i,j,temp,Size,pos;
Size=query[u].size();
for(i=;i<Size;i++)
{
L=R=flag=;
get_Num(query[u][i].x,);
if(flag)
{
ans[query[u][i].i].y=-;
continue;
}
ans[query[u][i].i].y+=L*;
ans[query[u][i].i].y+=Lsum-L;
ans[query[u][i].i].y+=R*;
ans[query[u][i].i].y+=Rsum-R;
ans[query[u][i].i].x+=R;
}
int f=;
for(i=head[u];i!=-;i=edge[i].next)
{
if(f)
{
Insert(w[u],,);
Rsum++;
}
else
{
Insert(w[u],,);
Lsum++;
}
f++;
dfs(edge[i].v);
if(f==)
{
del(w[u],,);
Rsum--;
}
else
{
del(w[u],,);
Lsum--;
}
}
}
int main()
{
int n,m,q,t,i,j,a,b,u,num;
scanf("%d",&t);
while(t--)
{
init();
num=;
scanf("%d",&n);
for(i=;i<=n;i++)
{
scanf("%d",w+i);
Index[i]=w[i];
}
sort(Index+,Index+n+);
num=;
for(i=;i<=n;i++)//将坐标离散化
if(Index[i]>Index[num])
Index[++num]=Index[i];
buildTree(,num,);//建立线段树
scanf("%d",&m);
for(i=;i<=m;i++)
{
scanf("%d%d%d",&u,&a,&b);
add(u,b);
add(u,a);
}
scanf("%d",&q);
Query temp;
int v;
for(i=;i<=q;i++)//将所有查询保存起来
{
scanf("%d%d",&v,&temp.x);
temp.i=i;
query[v].push_back(temp);
}
int f=;//标记走左还是右
for(i=head[];i!=-;i=edge[i].next)//从1号节点开始遍历
{
if(f)//若走右
{
Insert(w[],,);//将该值插入右线段树,并且总数加1
Rsum++;
}
else
{
Insert(w[],,);//插入左线段树,总数加1
Lsum++;
}
f++;
dfs(edge[i].v);
if(f==)
{
del(w[],,);//从右儿子退出,将其删除,总数减1
Rsum--;
}
else
{
del(w[],,);//从左儿子退出
Lsum--;
}
}
for(i=;i<=q;i++)
{
if(ans[i].y!=-)
printf("%d %d\n",ans[i].x,ans[i].y);
else
printf("0\n");
}
}
return ;
}
hdu 4605 线段树与二叉树遍历的更多相关文章
- 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 ...
- hdu 3974 线段树 将树弄到区间上
Assign the task Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 3436 线段树 一顿操作
Queue-jumpers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- hdu 3397 线段树双标记
Sequence operation Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- hdu 4578 线段树(标记处理)
Transformation Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others) ...
- hdu 4533 线段树(问题转化+)
威威猫系列故事——晒被子 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Tot ...
- hdu 2871 线段树(各种操作)
Memory Control Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- hdu 4052 线段树扫描线、奇特处理
Adding New Machine Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- hdu 1542 线段树扫描(面积)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
随机推荐
- Spring dependency checking with @Required Annotation
Spring's dependency checking in bean configuration file is used to make sure all properties of a cer ...
- [iOS微博项目 - 2.1] - 获得新浪授权接口
A.如何获得新浪的授权接口 登陆新浪的开放平台 注册新浪账号 创建应用 获得应用id和请求地址 查阅相关API 关联需要进行测试的账号 1.登陆开放平台 http://open.weibo.com ...
- C C++实现创建目录
下面代码是C.C++可以使用的创建目录的函数及头文件,这是引用的opencv,haartraining中的一种方式. #include <direct.h> //不同系统可能不一样,这是在 ...
- CodeForces 732D Exams (二分)
题意:某人要考试,有n天考m个科目,然后有m个科目要考试的时间和要复习多少天才能做,问你他最早考完所有科目是什么时间. 析:二分答案,然后在判断时,直接就是倒着判,很明显后出来的优先,也就是一个栈. ...
- WordPress主题制作教程[壹] - 了解WP&结构&索引
最近开始筹备WordPress主题开发了.首先我们在此章节中进行了解什么是WP,以及WP的结构.通过这个文章索引到以后所写的WP系列教程. (抱歉,大家不要急,持续更新中....) 1.首先,我们来认 ...
- Failed to load session “ubuntu” -- 12.04
在使用ubuntu 12.04的时候,之前不喜欢Unity桌面,就按照网上提示的安装了Gnome桌面,并且成功了! 可是,最近又想把Unity装回来,心想,这不就是安装一软件的活嘛,很简单!于是就卸载 ...
- ecshop的smarty库还原成smarty原生库方法
写过ecshop模板的人都晓得,他们是用所谓的dwt的文件来嵌套lbi文件进行模板的彼此调用.在咱们调取数据的时分,ecshop的默许模板只提供给咱们几个简略的句子进行调用,那么有没有办法能够把这个精 ...
- 使用Unity制作游戏关卡的教程(一)
转自: http://gamerboom.com/archives/74131 作者:Matthias Zarzecki 我正在制作<Looking For Group – The Fork O ...
- uva 10152 ShellSort
//这个算法用到了"相对位置"的思想,并且就本题而言还有一个很重要的结论就是,假设 //移动了k个元素,那么这k个元素一定是最后结果的那个序列的前k个元素,而且易知, //越先移动 ...
- java笔记-关于一些常用 且实用的开源包
作为一只从.net转java的程序猿..表示有些jdk原生的类很不习惯.. 1.时间处理 代替原生Calendar joda-time 框架.地址https://github.com/JodaOr ...