HDU - 4358
22935 단어 트리에 계발식 병합도론
제목 링크: HDU - 4358
현재 출현 횟수가 k인 개수를 직접 유지하고 아들의 답을 중시하며 폭력은 아들을 가볍게 계산하면 된다.
AC 코드:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include
//#define int long long
using namespace std;
const int N=1e5+10;
int n,k,q,sz[N],w[N],son[N],res[N],ans,mp[N];
vector<int> g[N],v;
inline void add(int a,int b){g[a].push_back(b),g[b].push_back(a);}
void dfs1(int x,int fa){
sz[x]=1;
for(auto to:g[x]) if(to!=fa){
dfs1(to,x); sz[x]+=sz[to];
if(sz[to]>sz[son[x]]) son[x]=to;
}
}
void del(int x,int fa){
if(mp[w[x]]==k) ans--; mp[w[x]]--;
for(auto to:g[x]) if(to!=fa) del(to,x);
}
void insert(int x,int fa){
if(mp[w[x]]==k) ans--; if(++mp[w[x]]==k) ans++;
for(auto to:g[x]) if(to!=fa) insert(to,x);
}
void dfs2(int x,int fa){
for(auto to:g[x]) if(to!=fa&&to!=son[x]){
dfs2(to,x); del(to,x);
}
if(son[x]) dfs2(son[x],x);
for(auto to:g[x]) if(to!=son[x]&&to!=fa) insert(to,x);
if(mp[w[x]]==k) ans--; if(++mp[w[x]]==k) ans++;
res[x]=ans;
}
void init(){
for(int i=1;i<=n;i++) g[i].clear(),son[i]=mp[i]=0;
ans=0; v.clear();
}
inline void solve(){
cin>>n>>k; init();
for(int i=1;i<=n;i++) scanf("%d",&w[i]),v.push_back(w[i]);
sort(v.begin(),v.end()),v.erase(unique(v.begin(),v.end()),v.end());
for(int i=1;i<=n;i++) w[i]=lower_bound(v.begin(),v.end(),w[i])-v.begin()+1;
for(int i=1,a,b;i<n;i++) scanf("%d %d",&a,&b),add(a,b);
dfs1(1,1); dfs2(1,1);
cin>>q;
for(int i=1,x;i<=q;i++) scanf("%d",&x),printf("%d
",res[x]);
}
signed main(){
int T; cin>>T;
for(int i=1;i<=T;i++){
printf("Case #%d:
",i),solve();
if(i!=T) puts("");
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
HDU 3631 Shortest Path(Floyd + 플러그인)제목: n개의 점 m줄 테두리(단방향 테두리)와 q차 조작을 드리겠습니다. 처음에는 모든 점이 표시가 없습니다. 두 가지 조작이 있습니다. 1.0 x: x를 표시하고 가까이 표시한 경우 "ERROR! At point...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.