hdu 3804树链剖分+离线操作
- /*
- 树链刨分+离线操作
- 题意:给你一棵树,和询问x,y
- 从节点x--节点1的小于等于y的最大值.
- 解:先建一个空树,将树的边权值从小到大排序,将询问y按从小到大排序
- 对于每次询问y将小于等于y的边权值的边加入,在进行询问将结果储存最后输出即可
- 易错点:要考虑到节点1到节点1的情况需特判。
- */
- #pragma comment(linker, "/STACK:102400000,102400000")
- #include<stdio.h>
- #include<string.h>
- #include<math.h>
- #include<algorithm>
- #include<iostream>
- using namespace std;
- #define N 110000
- #define inf 0x3fffffff
- int f[N];
- int top[N];
- int fa[N];
- int siz[N];
- int nu,yong;
- int head[N];
- int deep[N];
- int son[N];
- int w[N];
- int Max;
- struct node
- {
- int u,v,w,next,we;
- } bian[N*4],ff[N],fy[N];
- void init()
- {
- yong=nu=0;
- memset(head,-1,sizeof(head));
- memset(son,-1,sizeof(son));
- }
- void addedge(int u,int v,int w)
- {
- bian[yong].u=u;
- bian[yong].v=v;
- bian[yong].w=w;
- bian[yong].next=head[u];
- head[u]=yong++;
- }
- void dfs(int u,int father,int d)
- {
- deep[u]=d;
- fa[u]=father;
- siz[u]=1;
- int i;
- for(i=head[u]; i!=-1; i=bian[i].next)
- {
- int v=bian[i].v;
- if(v!=father)
- {
- dfs(v,u,d+1);
- siz[u]+=siz[v];
- if(son[u]==-1||siz[son[u]]<siz[v])
- son[u]=v;
- }
- }
- return ;
- }
- void getnu(int u,int cnt)
- {
- f[u]=nu++;
- top[u]=cnt;
- if(son[u]==-1)return ;
- getnu(son[u],cnt);
- int i;
- for(i=head[u]; i!=-1; i=bian[i].next)
- {
- int v=bian[i].v;
- if(v!=son[u]&&v!=fa[u])
- getnu(v,v);
- }
- return ;
- }
- int cmp(const void *a,const void *b)
- {
- return (*(struct node *)a).v-(*(struct node *)b).v;
- }
- int cmpp(const void *a,const void *b)
- {
- return (*(struct node *)a).w-(*(struct node *)b).w;
- }
- struct nodee
- {
- int l,r,maxx;
- } tree[N*4];
- int Ma(int v,int vv)
- {
- return v>vv?v:vv;
- }
- void pushup(int t)
- {
- tree[t].maxx=Ma(tree[t*2].maxx,tree[t*2+1].maxx);
- }
- void build(int t,int l,int r)
- {
- tree[t].l=l;
- tree[t].r=r;
- if(tree[t].l==tree[t].r)
- {
- tree[t].maxx=-1;
- return ;
- }
- int mid=(tree[t].l+tree[t].r)/2;
- build(t*2,l,mid);
- build(t*2+1,mid+1,r);
- pushup(t);
- }
- void update(int t,int x,int y)
- {
- if(tree[t].l==x&&tree[t].r==x)
- {
- tree[t].maxx=y;
- return ;
- }
- int mid=(tree[t].l+tree[t].r)/2;
- if(x<=mid)update(t*2,x,y);
- else
- update(t*2+1,x,y);
- pushup(t);
- }
- void qury(int t,int l,int r)
- {
- if(tree[t].l==l&&tree[t].r==r)
- {
- Max=Ma(Max,tree[t].maxx);
- return ;
- }
- int mid=(tree[t].l+tree[t].r)/2;
- if(r<=mid)qury(t*2,l,r);
- else if(l>mid)qury(t*2+1,l,r);
- else
- {
- qury(t*2,l,mid);
- qury(t*2+1,mid+1,r);
- }
- pushup(t);
- }
- int findmax(int u,int v)
- {
- if(u==v)return -1;//特判因为可能出现节点1到节点1的情况是不存在的
- int f1=top[u];
- int f2=top[v];
- int ans=-inf;
- while(f1!=f2)
- {
- if(deep[f1]<deep[f2])
- {
- swap(f1,f2);
- swap(u,v);
- }
- Max=-inf;
- qury(1,f[f1],f[u]);
- ans=Ma(ans,Max);
- u=fa[f1];
- f1=top[u];
- }
- if(u==v)return ans;
- if(deep[u]>deep[v]) swap(u,v);
- Max=-inf;
- qury(1,f[son[u]],f[v]);
- ans=Ma(ans,Max);
- return ans;
- }
- int main()
- {
- int n,i,j,k,t;
- scanf("%d",&t);
- while(t--)
- {
- scanf("%d",&n);
- init();
- for(i=1; i<n; i++)
- {
- scanf("%d%d%d",&ff[i].u,&ff[i].v,&ff[i].w);
- addedge(ff[i].u,ff[i].v,ff[i].w);
- addedge(ff[i].v,ff[i].u,ff[i].w);
- }
- dfs(1,1,0);//得到deep,fa,siz,son数组值
- getnu(1,1);//得到f,top的值
- for(i=1; i<n; i++)
- {
- if(deep[ff[i].u]<deep[ff[i].v])
- swap(ff[i].u,ff[i].v);
- w[ff[i].u]=ff[i].w;
- }
- build(1,1,nu-1);//建空树
- scanf("%d",&k);
- for(i=1; i<=k; i++)
- {
- scanf("%d%d",&fy[i].u,&fy[i].v);
- fy[i].w=i;//记录下标
- }
- qsort(fy+1,k,sizeof(fy[0]),cmp);//排序
- qsort(ff+1,n-1,sizeof(ff[0]),cmpp);
- for(i=1,j=1; i<=k; i++)
- {
- for(; j<n;)
- {
- if(fy[i].v>=ff[j].w)
- update(1,f[ff[j].u],ff[j].w);//加边
- else break;
- j++;
- }
- fy[i].we=findmax(1,fy[i].u);//查找
- }
- qsort(fy+1,k,sizeof(fy[0]),cmpp);//再次按下标排序
- for(i=1; i<=k; i++)//输出
- printf("%d\n",fy[i].we);
- }
- return 0;
- }
hdu 3804树链剖分+离线操作的更多相关文章
- hdu 3804 树链剖分
思路:将边权排序,然后插入线段树,这样就可以直接用二分查找确定答案. #pragma comment(linker, "/STACK:1024000000,1024000000") ...
- hdu 5893 (树链剖分+合并)
List wants to travel Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/O ...
- hdu 5052 树链剖分
Yaoge’s maximum profit Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/ ...
- hdu 4897 树链剖分(重轻链)
Little Devil I Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- hdu 5274 树链剖分
Dylans loves tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- HDU 3966 (树链剖分+线段树)
Problem Aragorn's Story (HDU 3966) 题目大意 给定一颗树,有点权. 要求支持两种操作,将一条路径上的所有点权值增加或减少ai,询问某点的权值. 解题分析 树链剖分模板 ...
- hdu 3966(树链剖分+线段树区间更新)
传送门:Problem 3966 https://www.cnblogs.com/violet-acmer/p/9711441.html 学习资料: [1]线段树区间更新:https://blog.c ...
- HDU 3966 /// 树链剖分+树状数组
题意: http://acm.hdu.edu.cn/showproblem.php?pid=3966 给一棵树,并给定各个点权的值,然后有3种操作: I x y z : 把x到y的路径上的所有点权值加 ...
- hdu 4729 树链剖分
思路:这个树链剖分其实还是比较明显的.将边按权值排序后插入线段树,然后用线段树查找区间中比某个数小的数和,以及这样的数的个数.当A<=B时,就全部建新的管子. 对于A>B的情况比较 建一条 ...
随机推荐
- printf的整型
参 数 说 明 %d 输出数字长为变量数值的实际长度 %md 输出m位(不足补空格,大于m位时按实际长度输出) %-md m含义同上.左对齐输出 %ld l(小写字母)表示输出“长整型”数据 %m1 ...
- Android项目模块化遇到的问题
1.问题背景 gradle 4 MacOs 10.14.3 Android Studio 3 在android模块化的时候,例如,有两个模块,一个是usercenter,另一个是common. 其中u ...
- SPFA+Dinic HDOJ 5294 Tricks Device
题目传送门 /* 题意:一无向图,问至少要割掉几条边破坏最短路,问最多能割掉几条边还能保持最短路 SPFA+Dinic:SPFA求最短路时,用cnt[i]记录到i最少要几条边,第二个答案是m - cn ...
- ACM_走楼梯Ⅱ
走楼梯Ⅱ Time Limit: 2000/1000ms (Java/Others) Problem Description: 有一楼梯共N+1级,刚开始时你在第一级,若每次能走M级(1<=M& ...
- Using 10053 Trace Events and get outline
When it comes to performance tuning, we can spend time on one or both ends of the problem. On the &q ...
- JavaScript 正则表达式(转自 mozilla)
正则表达式是被用来匹配字符串中的字符组合的模式.在JavaScript中,正则表达式也是对象. 这种模式可以被用于 RegExp 的 exec 和 test 方法以及 String 的 match.r ...
- 全面学习ORACLE Scheduler特性(5)Schedules调度Programs执行的Jobs
3.2 Schedules调度Programs执行的Jobs 通过schedule调度program的执行的job,看到这样的形容是不是让你彻底晕头了,就说明你还是没搞明白10g中SCHEDULERS ...
- 全面学习ORACLE Scheduler特性(2)管理jobs
1.2 管理Jobs 1.2.1 启用Jobs 前面创建JOB时,由于未显式的指定ENABLED参数,因此即使指定了START_DATE,不过默认情况下JOB不会自动执行.对于这种情况,DBMS_ ...
- CSS + radius 五环
使用CSS的外链方式,写了一个五环 CSS的布局 附加radius的使用 思路: 一个大盒子里放两个子盒子: 两个子盒子上下排列,分别放3个和2个盒子用来制作圆环: 大盒子给相对定位,连个子盒子设为绝 ...
- LN : leetcode 3 Longest Substring Without Repeating Characters
lc 3 Longest Substring Without Repeating Characters 3 Longest Substring Without Repeating Characters ...