• 2018 ACM 网络选拔赛 青岛赛区


    一些题目的代码被网站吞了……

    Problem B. Red Black Tree

    http://acm.zju.edu.cn/onlinejudge/searchProblem.do?contestId=1&titlefrom=0&authorfrom=0&sourcefrom=0&query=The+2018+ACM-ICPC+Asia+Qingdao+Regional+Contest%2C+Online

    http://acm.zju.edu.cn/pcpst/index.html

    http://acm.zju.edu.cn/contest-materials/qdol2018/qdol2018_problems.pdf

    注意是找祖先(红色孩子节点无效)!

    先按照花费对节点从大到小进行排序,依次增加一个点,这个点的花费采用从该点到所有新加入点的最近公共祖先的距离,直到遇到花费不可减少,则停止。

    注意maxlen!

      1 #include <bits/stdc++.h>
      2 #define ll long long
      3 using namespace std;
      4 const int maxn=1e5+10;
      5 const double minv=1e-10;
      6 const ll inf=1e18;
      7 
      8 vector<pair<int,ll> >e[maxn];
      9 int r[maxn],dep[maxn<<1],p[maxn<<1],lef[maxn],er[21],point[maxn],ind,f[maxn<<1][21];
     10 ll cost[maxn],len[maxn];
     11 bool vis[maxn];
     12 
     13 void dfs(int d,ll c,ll l,int deep)
     14 {
     15     vis[d]=1;
     16     if (r[d]==1)
     17         c=0;
     18     cost[d]=c;
     19     len[d]=l;
     20     dep[++ind]=deep;
     21     p[ind]=d;
     22     lef[d]=ind;
     23     vector<pair<int,ll> >::iterator j;
     24     for (j=e[d].begin();j!=e[d].end();j++)
     25         if (!vis[j->first])
     26         {
     27             dfs(j->first,c+j->second,l+j->second,deep+1);
     28             dep[++ind]=deep;
     29             p[ind]=d;
     30         }
     31 }
     32 
     33 int cmp(int a,int b)
     34 {
     35     return cost[a]>cost[b];
     36 }
     37 
     38 int main()
     39 {
     40     int t,n,m,q,u,v,d,deep,i,j,k;
     41     ll w,result,maxlen;
     42     for (i=0;i<=20;i++)
     43         er[i]=1<<i;
     44     scanf("%d",&t);
     45     while (t--)
     46     {
     47         scanf("%d%d%d",&n,&m,&q);
     48         for (i=1;i<=n;i++)
     49         {
     50             r[i]=0;
     51             vis[i]=0;
     52             e[i].clear();
     53         }
     54         for (i=1;i<=m;i++)
     55             scanf("%d",&d),r[d]=1;
     56         for (i=1;i<n;i++)
     57         {
     58             scanf("%d%d%lld",&u,&v,&w);
     59             e[u].push_back({v,w});
     60             e[v].push_back({u,w});
     61         }
     62         ind=0;
     63         dfs(1,0,0,0);
     64         for (j=1;j<=ind;j++)
     65             f[j][0]=j;
     66         deep=(int)(log(ind)/log(2)+minv);
     67         for (i=1;i<=deep;i++)
     68             for (j=1,k=er[i-1]+1;j<=ind-er[i]+1;j++,k++)
     69                 f[j][i]=(dep[f[j][i-1]]<dep[f[k][i-1]])?f[j][i-1]:f[k][i-1];
     70         while (q--)
     71         {
     72             scanf("%d",&m);
     73             for (i=1;i<=m;i++)
     74                 scanf("%d",&point[i]);
     75             sort(point+1,point+m+1,cmp);
     76             if (m==1)
     77                 result=0;
     78             else
     79             {
     80                 result=cost[point[2]];
     81                 d=point[1];
     82             }
     83             maxlen=len[point[1]];
     84             for (i=2;i<=m;i++)
     85             {
     86                 u=lef[d];
     87                 v=lef[point[i]];
     88                 if (u>v)
     89                     swap(u,v);
     90                 deep=(int)(log(v-u+1)/log(2)+minv);
     91                 d=(dep[f[u][deep]]<dep[f[v-er[deep]+1][deep]])?f[u][deep]:f[v-er[deep]+1][deep];
     92                 d=p[d];
     93                 maxlen=max(maxlen,len[point[i]]);
     94                 w=maxlen-len[d];
     95                 if (i==m || w>=cost[point[i+1]])
     96                 {
     97                     result=min(result,w);
     98                     break;
     99                 }
    100                 result=min(result,cost[point[i+1]]);
    101             }
    102             printf("%lld
    ",result);
    103         }
    104     }
    105     return 0;
    106 }
    107 /*
    108 10
    109 10 2 100
    110 7 10
    111 1 2 3
    112 1 3 4
    113 1 4 1
    114 2 5 1
    115 3 6 2
    116 5 7 3
    117 3 8 2
    118 4 9 3
    119 9 10 10
    120 5 1 2 3 4 5
    121 
    122 */

    另外:

    对花费采用二分

    参见 https://blog.csdn.net/qq_40993793/article/details/82762766,

    每次询问O( klog(w*n) ),(其中排序那块我没看懂,这里的时间复杂度没有算排序)

    sum(k)<=2e6,n<=1e5,w<=1e9,

    因此log(w*n)=47,maxtime=9.4*10^7,存在超时的可能性(虽然假设的有点。。。)。不太推荐。。。

     在zoj测试时,超时了

      1 #include <bits/stdc++.h>
      2 #define ll long long
      3 using namespace std;
      4 const int maxn=1e5+10;
      5 const double minv=1e-10;
      6 const ll inf=1e18;
      7 
      8 vector<pair<int,ll> >e[maxn];
      9 int red[maxn],dep[maxn<<1],p[maxn<<1],lef[maxn],er[21],point[maxn],ind,f[maxn<<1][21];
     10 ll cost[maxn],len[maxn];
     11 bool vis[maxn];
     12 
     13 void dfs(int d,ll c,ll l,int deep)
     14 {
     15     vis[d]=1;
     16     if (red[d]==1)
     17         c=0;
     18     cost[d]=c;
     19     len[d]=l;
     20     dep[++ind]=deep;
     21     p[ind]=d;
     22     lef[d]=ind;
     23     vector<pair<int,ll> >::iterator j;
     24     for (j=e[d].begin();j!=e[d].end();j++)
     25         if (!vis[j->first])
     26         {
     27             dfs(j->first,c+j->second,l+j->second,deep+1);
     28             dep[++ind]=deep;
     29             p[ind]=d;
     30         }
     31 }
     32 
     33 int cmp(int a,int b)
     34 {
     35     return cost[a]>cost[b];
     36 }
     37 
     38 int main()
     39 {
     40     int t,n,m,q,u,v,g,d,deep,i,j,k,l;
     41     ll w,result,r;
     42     bool use;
     43     for (i=0;i<=20;i++)
     44         er[i]=1<<i;
     45     scanf("%d",&t);
     46     while (t--)
     47     {
     48         scanf("%d%d%d",&n,&m,&q);
     49         for (i=1;i<=n;i++)
     50         {
     51             red[i]=0;
     52             vis[i]=0;
     53             e[i].clear();
     54         }
     55         for (i=1;i<=m;i++)
     56             scanf("%d",&d),red[d]=1;
     57         for (i=1;i<n;i++)
     58         {
     59             scanf("%d%d%lld",&u,&v,&w);
     60             e[u].push_back({v,w});
     61             e[v].push_back({u,w});
     62         }
     63         ind=0;
     64         dfs(1,0,0,0);
     65         for (j=1;j<=ind;j++)
     66             f[j][0]=j;
     67         deep=(int)(log(ind)/log(2)+minv);
     68         for (i=1;i<=deep;i++)
     69             for (j=1,k=er[i-1]+1;j<=ind-er[i]+1;j++,k++)
     70                 f[j][i]=(dep[f[j][i-1]]<dep[f[k][i-1]])?f[j][i-1]:f[k][i-1];
     71         while (q--)
     72         {
     73             l=0; r=0;
     74             scanf("%d",&g);
     75             for (i=1;i<=g;i++)
     76             {
     77                 scanf("%d",&point[i]);
     78                 r=max(r,cost[point[i]]);
     79             }
     80             while (l<=r)
     81             {
     82                 m=(l+r)>>1;
     83                 use=0;
     84                 for (i=1;i<=g;i++)
     85                     if (cost[point[i]]>m)
     86                     {
     87                         if (!use)
     88                         {
     89                             use=1;
     90                             d=point[i];
     91                             continue;
     92                         }
     93                         u=lef[d];
     94                         v=lef[point[i]];
     95                         if (u>v)
     96                             swap(u,v);
     97                         deep=(int)(log(v-u+1)/log(2)+minv);
     98                         d=(dep[f[u][deep]]<dep[f[v-er[deep]+1][deep]])?f[u][deep]:f[v-er[deep]+1][deep];
     99                         d=p[d];
    100                         if (len[point[1]]-len[d]>m)
    101                             break;
    102                     }
    103                 if (i==g+1)
    104                     r=m-1;
    105                 else
    106                     l=m+1;
    107             }
    108             printf("%lld
    ",l);
    109         }
    110     }
    111     return 0;
    112 }
    113 /*
    114 10
    115 10 2 100
    116 7 10
    117 1 2 3
    118 1 3 4
    119 1 4 1
    120 2 5 1
    121 3 6 2
    122 5 7 3
    123 3 8 2
    124 4 9 3
    125 9 10 10
    126 5 1 2 3 4 5
    127 
    128 */
  • 相关阅读:
    线性代数:矩阵行列式
    线性代数:逆变换
    线性代数:线性变换
    线性代数:零空间
    线性代数:向量乘法
    线性代数基础:向量组合
    线性代基础理论:向量
    线性代基础理论:矩阵
    SpringBoot 消费NSQ消息
    将Oracle中的数据放入elasticsearch
  • 原文地址:https://www.cnblogs.com/cmyg/p/9874226.html
Copyright © 2020-2023  润新知