zoukankan      html  css  js  c++  java
  • hdu 4358 深搜时间戳+线段树更新

    其实这道题真的告诉了我一个道理,那就是仔细看题,题目中明确说出了1就是所有子树的根结点。

    我们可以想一想,现在每个结点代表着一段区间的询问,所以我们必须利用深搜的时间戳来找出所有结点所代表的区间。

    前向星见图自然不可少。

    更新区间的话,我们必须用离线处理,[i,j]这个区间代表着第i个数在这个区内出现k次的数的个数。

    View Code
      1 #include<algorithm>
      2 #include<iostream>
      3 #include<string.h>
      4 #include<cstdio>
      5 #include<vector>
      6 #include<map>
      7 #include<stdlib.h>
      8 using std::sort;
      9 using std::vector;
     10 using std::map;
     11 const int N = 100111;
     12 map<int,int> q;
     13 vector<int> p[N];
     14 struct Edge
     15 {
     16        int e,next;
     17 }edge[N<<1];
    
     18 int head[N],weight[N],visit[N],Ti;
     19 struct Query
     20 {
     21      int l,r,id;
     22      bool operator <(const Query & tmp)const
     23      {
     24          return r<tmp.r;
     25      }
     26 }que[N];
     27 struct node
     28 {
     29      int l,r;
     30 }No[N];
     31 int cover[N<<2],num[N],ans[N];
     32 void dfs(int u)
     33 {
     34      No[u].l=Ti;
     35      num[Ti]=weight[u];
     36      for(int i=head[u];i!=-1;i=edge[i].next)
     37      {
     38          if(visit[edge[i].e]==0)
     39          {
     40              visit[u]=1;
     41              Ti++;
     42              dfs(edge[i].e);
     43          }
     44      }
     45      No[u].r=Ti;
     46 }
     47 void PushDown(int t)
     48 {
     49      if(cover[t])
     50      {
     51          int t1=t<<1,t2=t1|1;
     52          cover[t1]+=cover[t];
     53          cover[t2]+=cover[t];
     54          cover[t]=0;
     55      }
     56      return ;
     57 }
     58 void update(int t,int l,int r,int L,int R,int val)
     59 {
     60      if(L<=l&&r<=R)
     61      {
     62          cover[t]+=val;
     63          return ;
     64      }
     65      PushDown(t);
     66      int m=(r+l)>>1;
     67      if(L<=m)update(t<<1,l,m,L,R,val);
     68      if(R>m)update(t<<1|1,m+1,r,L,R,val);
     69 }
     70 int query(int t,int l,int r,int i)
     71 {
     72      if(l==r)return cover[t];
     73      PushDown(t);
     74      int m=(l+r)>>1;
     75      if(i<=m)return query(t<<1,l,m,i);
     76      else return query(t<<1|1,m+1,r,i);
     77 }
     78 int main()
     79 {
     80     int t;
     81     int n,k,u,v,Q,T=0;
     82     scanf("%d",&t);
     83     while(t--)
     84     {
     85           scanf("%d%d",&n,&k);
     86           q.clear();
     87           int pos=1;
     88           for(int i=1;i<=n;i++)
     89           {
     90               scanf("%d",&weight[i]);
     91               if(q[weight[i]]==0)q[weight[i]]=pos++;
     92               weight[i]=q[weight[i]];
     93               head[i]=-1,visit[i]=0;
     94           }
     95           int tope=0;
     96           for(int i=0;i<pos;i++)
     97               p[i].clear();
     98           for(int i=1;i<n;i++)
     99           {
    100               scanf("%d%d",&u,&v);
    101               edge[tope].e=v;
    102               edge[tope].next=head[u];
    103               head[u]=tope++;
    104               edge[tope].e=u;
    105               edge[tope].next=head[v];
    106               head[v]=tope++;
    107           }
    108           visit[1]=Ti=1;
    109           dfs(1);
    110           scanf("%d",&Q);
    111           for(int i=1;i<=Q;i++)
    112           {
    113               scanf("%d",&u);
    114               que[i].l=No[u].l;
    115               que[i].r=No[u].r;
    116               que[i].id=i;
    117           }
    118           sort(que+1,que+Q+1);
    119           memset(cover,0,sizeof(cover));
    120           for(int i=1,j=1;i<=n;i++)
    121           {
    122               p[num[i]].push_back(i);
    123               int Count=p[num[i]].size();
    124               if(Count>k)
    125               {
    126                   update(1,1,n,1,p[num[i]][Count-k-1],-1);
    127                   update(1,1,n,p[num[i]][Count-k-1]+1,p[num[i]][Count-k],1);
    128               }
    129               else
    130                 if(Count==k)
    131                    update(1,1,n,1,p[num[i]][Count-k],1);
    132               while(i>=que[j].r)
    133               {
    134                   ans[que[j].id]=query(1,1,n,que[j].l);
    135                   j++;
    136                   if(j>Q)break;
    137               }
    138               if(j>Q)break;
    139           }
    140           if(T!=0)printf("\n");
    141           printf("Case #%d:\n",++T);
    142           for(int i=1;i<=Q;i++)
    143               printf("%d\n",ans[i]);
    144     }
    145     return 0;
    146 }
  • 相关阅读:
    JQuery图片局部放大
    c# .net 如何使用log4net记录日志
    VS2010添加自定义的项目模板及项模板
    Virtualbox运行报cannot access the kernel driver的解决方法
    Session超时设置
    WebBrowser 错误处理
    asp.net MVC 2 自定义用户角色权限设计
    c# 调用CMD不显窗口
    C#遍历CookieContainer所有Cookie并保存到文件
    Application,Session,Cookie,ViewState和Cache区别
  • 原文地址:https://www.cnblogs.com/nuoyan2010/p/2785579.html
Copyright © 2011-2022 走看看