题目链接:

Problem: Query on the tree

Time limit: 1s     Mem limit: 64 MB     
Problem Description

There is a tree with n node, labeled from 1 to n, and the root of the tree is 1.

For every node i, if its father is j, its value vi=vj*i%20161119, the value of the root is 1.

Now monster has q queries, for each query, monster give you a node i and a number k (0<=k<20161119),

you should find a node j in i’s subtree to minimize abs(k-vj).

Input

Multiple cases.

In first line there is a number n (n<=1e5), then next n-1 lines, each describes an edge of

the tree.

Next line there is a number q(q<=1e5), then next q lines, each contains two numbers i and k.

Output

Each line output a single number, the minimum number of abs(vj-k).

Sample Input
7 1 2 1 3 2 4 2 5 3 6 3 7 5 1 4 2 7 3 30 6 0 7 7
Sample Output
1 1 9 18 14
 
题意:给出一棵树和每个节点的点权,现在m个询问,每个询问是问在一个节点的子树上找到一个节点是得那个式子的值最小;
 
思路:dfs序之后可以得到每个点的子树对应的区间,然后再在这个区间里面找到一个最接近k的节点值,可以二分第x大,然后找到k附近的那一个或者两个数求得答案;
 
代码:
 
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=1e5+10;
int n,m,first[maxn],last[maxn],cnt;
int val[maxn];
vector<int>ve[maxn];
int a[maxn],tree[32][maxn],sorted[maxn],num[32][maxn]; template<class T> void read(T&num) {
char CH; bool F=false;
for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
F && (num=-num);
}
int stk[70], tp;
template<class T> inline void print(T p) {
if(!p) { puts("0"); return; }
while(p) stk[++ tp] = p%10, p/=10;
while(tp) putchar(stk[tp--] + '0');
putchar('\n');
} void dfs(int cur,int fa)
{
val[cur]=(int)((LL)val[fa]*cur%20161119);
int len=ve[cur].size();
a[++cnt]=(int)val[cur];
first[cur]=cnt;
for(int i=0;i<len;i++)
{
int x=ve[cur][i];
if(x==fa)continue;
dfs(x,cur);
}
last[cur]=cnt;
}
void build(int dep,int l,int r)
{
if(l>=r)return ;
int mid=(l+r)>>1;
int lp=l,rp=mid+1,sum=mid-l+1;
for(int i=l;i<=r;i++)
{
if(tree[dep][i]<sorted[mid])sum--;
}
for(int i=l;i<=r;i++)
{
if(i!=l)num[dep][i]=num[dep][i-1];
else num[dep][i]=0;
if(tree[dep][i]<sorted[mid])
{
tree[dep+1][lp++]=tree[dep][i];
num[dep][i]++;
}
else if(tree[dep][i]==sorted[mid]&&sum>0)
{
tree[dep+1][lp++]=tree[dep][i];
num[dep][i]++;
sum--;
}
else
{
tree[dep+1][rp++]=tree[dep][i];
}
}
build(dep+1,l,mid),
build(dep+1,mid+1,r);
}
int query(int dep,int l,int r,int ql,int qr,int k)
{
if(l>=r)return tree[dep][l];
int mid=(l+r)>>1,s,ss;
if(l!=ql)s=num[dep][ql-1],ss=num[dep][qr]-num[dep][ql-1];
else s=0,ss=num[dep][qr];
if(k<=ss)return query(dep+1,l,mid,l+s,l+s+ss-1,k);
else return query(dep+1,mid+1,r,mid+1+ql-l-s,mid+1+qr-l-s-ss,k-ss);
}
inline int solve(int L,int R,int k)
{
int ans=1e9;
int l=1,r=R-L+1;
while(l<=r)
{
int mid=(l+r)>>1;
if(query(0,1,cnt,L,R,mid)<=k)l=mid+1;
else r=mid-1;
}
int pos=l-1;
if(pos)
{
ans=min(ans,abs(k-query(0,1,cnt,L,R,pos)));
if(pos<=R-L)ans=min(ans,abs(k-query(0,1,cnt,L,R,pos+1)));
}
else ans=min(ans,abs(k-query(0,1,cnt,L,R,pos+1)));
return ans;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
int u,v;
cnt=0;val[0]=1;
for(int i=0;i<=n;++i)
{
ve[i].clear();
for(int j=0;j<32;++j)
tree[j][i]=num[j][i]=0;
}
for(int i=1;i<n;++i)
{
read(u);read(v);
ve[u].push_back(v);
ve[v].push_back(u);
}
dfs(1,0);
for(int i=1;i<=cnt;++i)sorted[i]=tree[0][i]=a[i];
sort(sorted+1,sorted+cnt+1);
build(0,1,cnt);
read(m);
while(m--)
{
read(u);read(v);
int L=first[u],R=last[u];
print(solve(L,R,v));
}
}
return 0;
}

  

Problem: Query on the tree(二分+划分树)的更多相关文章

  1. SPOJ PT07J - Query on a tree III(划分树)

    PT07J - Query on a tree III #tree You are given a node-labeled rooted tree with n nodes. Define the ...

  2. BZOJ_1803_Spoj1487 Query on a tree III_主席树+dfs序

    BZOJ_1803_Spoj1487 Query on a tree III_主席树 Description You are given a node-labeled rooted tree with ...

  3. hdu4417(Super Mario)—— 二分+划分树

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  4. hdu 4836 The Query on the Tree(线段树or树状数组)

    The Query on the Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  5. SPOJ 375. Query on a tree (动态树)

    375. Query on a tree Problem code: QTREE You are given a tree (an acyclic undirected connected graph ...

  6. SP1487 PT07J - Query on a tree III (主席树)

    SP1487 PT07J - Query on a tree III 题意翻译 你被给定一棵带点权的n个点的有根数,点从1到n编号. 定义查询 query(x,k): 寻找以x为根的k大点的编号(从小 ...

  7. 【BZOJ1803】Spoj1487 Query on a tree III 主席树+DFS序

    [BZOJ1803]Spoj1487 Query on a tree III Description You are given a node-labeled rooted tree with n n ...

  8. HDU 6191 Query on A Tree(字典树+离线)

    Query on A Tree Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Othe ...

  9. BZOJ3637 Query on a tree VI(树链剖分+线段树)

    考虑对于每一个点维护子树内与其连通的点的信息.为了换色需要,记录每个点黑白两种情况下子树内连通块的大小. 查询时,找到深度最浅的同色祖先即可,这可以比较简单的树剖+线段树乱搞一下(似乎就是qtree3 ...

随机推荐

  1. hdu 1686 Oulipo kmp算法

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1686 题目: Problem Description The French author George ...

  2. redis 笔记03 RDB 持久化、AOF持久化、事件、客户端

    RDB 持久化 1. RDB文件用于保存和还原Redis服务器所有数据库中的所有键值对数据. 2. SAVE命令由服务器进程直接执行保存操作,所以该命令会阻塞服务器. 3. BGSAVE由子进程执行保 ...

  3. 【Head First Servlets and JSP】笔记20:EL以及<jsp:useBean ....>的补充

    1.EL的英文是Expression Language,译成中文就是“表达式语言”.这是一种给前端程序员使用的脚本语言,EL与Java表达式相比并没有什么“天壤之别”,在后端程序员看来多少有点“多此一 ...

  4. oracle 11 g数据库卸载(方法二)

    1.开始->设置->控制面板->管理工具->服务 停止所有 Oracle服务. 2.开始->程序->Oracle - OraHome81->Oracle In ...

  5. Unix下 五种 I/O模型

    Unix下共有五种I/O模型: 1. 阻塞式I/O  2. 非阻塞式I/O  3. I/O复用(select和poll)  4. 信号驱动式I/O(SIGIO)  5. 异步I/O(POSIX的aio ...

  6. Book Review of “The practice of programming” (Ⅲ)

    The practice of programming Chapter 3 Design and Implementation In this section, we focus on one kin ...

  7. COS-4进程及进程管理

    操作系统是用户和计算机的接口,同时也是计算机硬件和其他软件的接口.操作系统的功能包括管理计算机系统的硬件.软件及数据资源,控制程序运行,改善人机界面,为其它应用软件提供支持,让计算机系统所有资源最大限 ...

  8. tcp连接的建立与释放

    1.TCP是面向连接的协议. 运输连接时用来传送TCP报文的.TCP运输连接的建立和释放是每一次面向连接的通信中必不可少的过程.因此,运输链接就有三个阶段,即:连接建立.数据传送和连接释放. 在TCP ...

  9. mysql——jdbc驱动下载&连接mysql例子

    mysql-connector-java-5.1.46.zip[解压后里面jar文件就是所需要的] https://dev.mysql.com/get/Downloads/Connector-J/my ...

  10. NO.4 Android开发中常用框架及工具

    android-pulltorefresh 一个强大的拉动刷新开源项目,支持各种控件下拉刷新ListView.ViewPager.WevView.ExpandableListView.GridView ...