弱啊弱啊,我用了扩展指令,然后大牛告诉我,只对VC++有用,对G++没用的。。shit,三题就这样没了。

方法是使用ST在线算法,O(1)查询,然后用线段树维护。。呃感觉这个好慢。看了大斌神的是用LCA倍增+维护一个表 ,得学习一下。。。

先贴弱的代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cstring>
  5. #pragma comment(linker, "/STACK:102400000,102400000")
  6. using namespace std;
  7.  
  8. const int N=300015;
  9.  
  10. struct Edge{
  11. int u,v,next;
  12. }edge[N*2];
  13. int head[N],tot,dtot;
  14. int dp[N*2][20];
  15. int ver[2*N],R[2*N],first[N],dir[N];
  16. bool vis[N];
  17. int ans;
  18. int tag[N*4];
  19.  
  20. void addedge(int u,int v){
  21. edge[tot].u=u;
  22. edge[tot].v=v;
  23. edge[tot].next=head[u];
  24. head[u]=tot++;
  25. }
  26.  
  27. void dfs(int u ,int dep) {
  28. vis[u] = true; ver[++dtot] = u; first[u] = dtot; R[dtot] = dep;
  29. for(int k=head[u]; k!=-1; k=edge[k].next)
  30. if( !vis[edge[k].v] ) {
  31. int v = edge[k].v ;
  32. dfs(v,dep+1);
  33. ver[++dtot] = u; R[dtot] = dep;
  34. }
  35. }
  36.  
  37. void ST(int n) {
  38. for(int i=1;i<=n;i++)
  39. dp[i][0] = i;
  40. for(int j=1;(1<<j)<=n;j++) {
  41. for(int i=1;i+(1<<j)-1<=n;i++) {
  42. int a = dp[i][j-1] , b = dp[i+(1<<(j-1))][j-1];
  43. dp[i][j] = R[a]<R[b]?a:b;
  44. }
  45. }
  46. }
  47.  
  48. int RMQ(int l,int r) {
  49. int k=0;
  50. while((1<<(k+1))<=r-l+1)
  51. k++;
  52. int a = dp[l][k], b = dp[r-(1<<k)+1][k];
  53. return R[a]<R[b]?a:b;
  54. }
  55.  
  56. int LCA(int u ,int v) {
  57. int x = first[u] , y = first[v];
  58. if(x > y) swap(x,y);
  59. int res = RMQ(x,y);
  60. return ver[res];
  61. }
  62.  
  63. void query(int rt,int l,int r,int L,int R){
  64. // cout<<L<<" "<<R<<endl;
  65. if(tag[rt]!=-1&&l<=L&&R<=r){
  66. if(ans==-1) ans=tag[rt];
  67. else {
  68. ans=LCA(ans,tag[rt]);
  69. }
  70. return ;
  71. }
  72. else if(L==R){
  73. // cout<<L<<" "<<ans<<endl;
  74. tag[rt]=L;
  75. if(ans==-1)
  76. ans=L;
  77. else{
  78. ans=LCA(ans,L);
  79. }
  80. return ;
  81. }
  82. int m=(L+R)>>1;
  83. if(r<=m){
  84. query(rt<<1,l,r,L,m);
  85. }
  86. else if(l>=m+1){
  87. query(rt<<1|1,l,r,m+1,R);
  88. }
  89. else{
  90. query(rt<<1,l,r,L,m);
  91. query(rt<<1|1,l,r,m+1,R);
  92. }
  93. if(tag[rt<<1]!=-1&&tag[rt<<1|1]!=-1)
  94. tag[rt]=LCA(tag[rt<<1],tag[rt<<1|1]);
  95. }
  96.  
  97. int main(){
  98. int n,q,u,v;
  99. while(scanf("%d",&n)!=EOF){
  100. memset(head,-1,sizeof(int)*(n+5));
  101. memset(vis,false,sizeof(bool)*(n+5));
  102. memset(tag,-1,sizeof(int)*(n*4));
  103. tot=0;
  104. for(int i=1;i<n;i++){
  105. scanf("%d%d",&u,&v);
  106. addedge(u,v);
  107. addedge(v,u);
  108. }
  109. dtot=0;
  110. dfs(1,1);
  111. ST(2*n-1);
  112. tag[1]=1;
  113. scanf("%d",&q);
  114. // printf("%d",LCA(2,3));
  115. // printf("%d",LCA(1,2));
  116. // printf("%d",LCA(3,4));
  117. while(q--){
  118. scanf("%d%d",&u,&v);
  119. ans=-1;
  120. query(1,u,v,1,n);
  121. printf("%d\n",ans);
  122. }
  123. }
  124. return 0;
  125. }

  

BC ROUND 43# 03 HDU 5266的更多相关文章

  1. BestCoder Round #43

    T1:pog loves szh I(hdu 5264) 题目大意: 给出把AB两个字符串交叉拼起来的结果,求出原串. 题解: 不解释..直接每次+2输出. T2:pog loves szh II(h ...

  2. HDU 5266 pog loves szh III (线段树+在线LCA转RMQ)

    题目地址:HDU 5266 这题用转RMQ求LCA的方法来做的很easy,仅仅须要找到l-r区间内的dfs序最大的和最小的就能够.那么用线段树或者RMQ维护一下区间最值就能够了.然后就是找dfs序最大 ...

  3. hdu 5266 pog loves szh III(lca + 线段树)

    I - pog loves szh III Time Limit:6000MS     Memory Limit:131072KB     64bit IO Format:%I64d & %I ...

  4. Educational Codeforces Round 43 (Rated for Div. 2)

    Educational Codeforces Round 43 (Rated for Div. 2) https://codeforces.com/contest/976 A #include< ...

  5. 字符串处理 BestCoder Round #43 1001 pog loves szh I

    题目传送门 /* 字符串处理:是一道水题,但是WA了3次,要注意是没有加'\0'的字符串不要用%s输出,否则在多组测试时输出多余的字符 */ #include <cstdio> #incl ...

  6. 贪心/二分查找 BestCoder Round #43 1002 pog loves szh II

    题目传送门 /* 贪心/二分查找:首先对ai%=p,然后sort,这样的话就有序能使用二分查找.贪心的思想是每次找到一个aj使得和为p-1(如果有的话) 当然有可能两个数和超过p,那么an的值最优,每 ...

  7. Educational Codeforces Round 43

    Educational Codeforces Round 43  A. Minimum Binary Number 显然可以把所有\(1\)合并成一个 注意没有\(1\)的情况 view code / ...

  8. HDU 5266 bc# 43 LCA+跳表

    学了一发LCA的倍增算法+跳表维护. 先说说LCA倍增算法,思路是fa[i][j]求的是i结点的2^j倍的祖先,其中2^0就是父结点了.所以可以递推fa[i][j]=fa[fa[i][j-1]][j- ...

  9. HDU 5618 Jam's problem again CDQ分治 BC ROUND 70

    题意:给你1e5个点(x,y,z),对于每一个点询问有多少个点(x1,y1,z1)满足x1<=x&&y1<=y&&z1<=z 分析:(官方题解奉上)很 ...

随机推荐

  1. AcWing算法基础1.1

    排序 快速排序(快排) 写题的时候用的不多基本都是直接sort ( ),面试可能要手撸快排,上模板 void quick_sort(int q[], int l, int r) { if(l > ...

  2. 【BZOJ2149】拆迁队(斜率优化DP+CDQ分治)

    题目: 一个斜率优化+CDQ好题 BZOJ2149 分析: 先吐槽一下题意:保留房子反而要给赔偿金是什么鬼哦-- 第一问是一个经典问题.直接求原序列的最长上升子序列是错误的.比如\(\{1,2,2,3 ...

  3. python爬虫之处理验证码

    云打码实现处理验证码 处理验证码,我们需要借助第三方平台来帮我们处理,个人认为云打码处理验证码的准确度还是可以的 首先第一步,我们得先注册一个云打码的账号,普通用户和开发者用户都需要注册一下 然后登陆 ...

  4. ACM_Jack拆炸弹(深搜)

    Jack拆炸弹 Time Limit: 2000/1000ms (Java/Others) Problem Description: 在一个由n*n个格子组成的监狱里被恐怖份子安置了一个定时炸弹.其中 ...

  5. C#语言最基础的数组和集合

    数组的书写格式:数据类型[]变量名=new 数据类型[长度]: 集合的书写格式:List<变量类型>变量名=new List<变量类型>(): 集合添加元素:变量名.Add(数 ...

  6. Android ScrollView里嵌套RecyclerView时,在RecyclerView上滑动时出现卡顿(冲突)的现象

    最近在项目中遇到一个现象,一个界面有一个RecyclerView(GridView型的),外面套了一层ScrollView,通过ScrollView上下滚动,但是在滑动的时候如果是在RecyclerV ...

  7. Android项目实战_手机安全卫士进程管理

    ###1.设备进程信息获取获取设备运行进程 ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVI ...

  8. JS——数组

    concat:连接两个或多个数组,返回被连接数组的一个副本. var arr1 = [12, "你好", "哈哈"] var arr2 = [12, " ...

  9. vim下阅读代码时标签跳转设置

    1.在fedora14中的 /etc/vimrc下,加入如下几行,可根据源代码工程文件的结构来定 2. 在源代码工程内,输入如下命令 ctags -R 当前目录下将生成一个tags文件 3.查看源代码 ...

  10. 可以用作javascript异步模式的函数写法

    1. 回调函数 f1(); f2(); function f1(callback) { setTimeout(function() { // f1的任务代码 callback(); }, 1000); ...