• 树的直径+rmq+(伪)单调队列 -HDU4123


    给定一棵n个点并且有边权的树,每个点的权值为该点能走的最远长度,并输入m个询问,每次询问最多有多少个编号连续的点,他们的最大最小点权差小于等于Q。N<=50000 M<=500 Q<=10000000

      我们知道一个点能走的最远端点一定是树的直径的端点,所以我们只需从树的直径两端点dfs,就可以求出每个点能到的最远长度。。然后rmq+尺取即可。

    这道题如果用系统的log会tle,所以必须手打log2。原理会再放一篇博客。

      1 #include <cctype>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <algorithm>
      6 using namespace std;
      7 
      8 const int maxn=50005, maxmi=18, INF=1e9;
      9 //const double exp=1e-6;
     10 int n, m, cntedge, maxdist, maxdistpos;
     11 int fir[maxn], val[maxn];
     12 int fmaxm[maxn][maxmi], fminm[maxn][maxmi];
     13 struct Edge{
     14     int to, v, next;
     15 };
     16 Edge edge[maxn];
     17 
     18 void addedge(int x, int y, int z){
     19     ++cntedge;
     20     Edge &nowedge1=edge[cntedge];
     21     nowedge1.to=y, nowedge1.v=z, nowedge1.next=fir[x];
     22     fir[x]=cntedge;
     23     ++cntedge;
     24     Edge &nowedge2=edge[cntedge];
     25     nowedge2.to=x, nowedge2.v=z, nowedge2.next=fir[y];
     26     fir[y]=cntedge;
     27     return;
     28 }
     29 
     30 void dfs(int now, int par, int dist){
     31     int nowedge, nowson;
     32     nowedge=fir[now];
     33     while (nowedge){
     34         nowson=edge[nowedge].to;
     35         if (nowson==par){
     36             nowedge=edge[nowedge].next;
     37             continue;
     38         }
     39         dfs(nowson, now, dist+edge[nowedge].v);
     40         nowedge=edge[nowedge].next;
     41     }
     42     if (dist>val[now]) val[now]=dist;
     43     if (dist>maxdist){
     44         maxdist=dist;
     45         maxdistpos=now;
     46     }
     47     return;
     48 }
     49 
     50 int flog2(float x) {
     51     return ((unsigned&)x>>23&255)-127;
     52 }
     53 int dvalue(int head, int tail){
     54     int maxm=0, minm=1e9;
     55     int lognum=flog2(tail-head+1);
     56     maxm=max(fmaxm[head][lognum], fmaxm[tail-(1<<lognum)+1][lognum]);
     57     minm=min(fminm[head][lognum], fminm[tail-(1<<lognum)+1][lognum]);
     58     return maxm-minm;
     59 }
     60 
     61 void init(){
     62     memset(fir, 0, sizeof(fir));
     63     memset(val, 0, sizeof(val));
     64     for (int i=0; i<maxn; ++i){
     65         edge[i].next=edge[i].to=edge[i].v=0;
     66     }
     67     cntedge=0;
     68 }
     69 
     70 int ri(){
     71     char c;
     72     int flag=1, r=0;
     73     do{
     74         c=getchar();
     75         if (c=='-') flag=-1;
     76     } while (!isgraph(c));
     77     do{
     78         r=r*10+c-48;
     79         c=getchar();
     80     } while (isgraph(c));
     81     return r*flag;
     82 }
     83 
     84 int main(){
     85     int x, y, z;
     86     while (~scanf("%d%d", &n, &m)){
     87         if (n==0&&m==0) break;
     88         init();
     89         for (int i=1; i<n; ++i){
     90             x=ri(), y=ri(), z=ri();
     91             addedge(x, y, z);
     92         }
     93         int s=1, far1, far2;
     94         maxdist=0, dfs(s, 0, 0);
     95         far1=maxdistpos;
     96         maxdist=0, dfs(far1, 0, 0);
     97         far2=maxdistpos;
     98         maxdist=0, dfs(far2, 0, 0);
     99         //for (int i=1; i<=n; ++i)
    100         //printf("%d
    ", val[i]);
    101         int q=0;
    102         for (int i=1; i<=n; ++i)
    103             fmaxm[i][0]=fminm[i][0]=val[i];
    104         for (int i=1; i<maxmi; ++i){
    105             for (int j=1; j<=n-(1<<i)+1; ++j){
    106                 fmaxm[j][i]=max(fmaxm[j][i-1], fmaxm[j+(1<<(i-1))][i-1]);
    107                 fminm[j][i]=min(fminm[j][i-1], fminm[j+(1<<(i-1))][i-1]);
    108             }
    109         }
    110         int h=1, t=1, maxm=0;
    111         for (int i=0; i<m; ++i){
    112             q=ri();
    113             h=1, t=1, maxm=0;
    114             while (t<=n){
    115                 if (dvalue(h, t)<=q) ++t;
    116                 else ++h;
    117                 if ((t-h)>maxm) maxm=t-h;
    118             }
    119             printf("%d
    ", maxm);
    120         }
    121     }
    122     return 0;
    123 }
  • 相关阅读:
    WM平台玩转Android全攻略
    WP7实时监控内存转
    Silverlight内存释放的方法
    .net中同步多个ScrollViewer滚动的四种方法
    windows phone7,zune:can't connect to your phone WP7手机无法连接Zune 的解决方法
    64位虚拟机Guest OS安装错误:0xC0000225
    Tip: Resharper 中 "Unknown Comment" 问题的解决办法
    工具: 删除Visual Studio项目中文件链接,并把原文件复制到相应的目录
    一个代表年月的类YearMonth
    在64bit Win2008上运行Asp + Access网站
  • 原文地址:https://www.cnblogs.com/MyNameIsPc/p/7446688.html
Copyright © 2020-2023  润新知