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 }