#include<bits/stdc++.h> #define MAXN 300005 #define MAXM 25 usingnamespace std; inlineintread(){ int x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9') { if (ch=='-') f=-1; ch=getchar(); } while (ch>='0'&&ch<='9') { x=(x*10)+(ch-'0'); ch=getchar(); } return x*f; } vector<int>G[MAXN]; inlinevoidAddEdge(int u,int v){ G[u].push_back(v); } namespace L__C__A__Desu{//简单LCA int anc[MAXN][MAXM],dep[MAXN]; voiddfs(int u,int father){ anc[u][0]=father; for (registerint i=1;i<MAXM;++i) anc[u][i]=anc[anc[u][i-1]][i-1]; for (registerint i=0;i<G[u].size();++i){ int v=G[u][i]; if (v!=father){ dep[v]=dep[u]+1; dfs(v,u); } } } inlineintLCA(int u,int v){ if (u==v) return u; if (dep[u]<dep[v]) swap(u,v); for (registerint i=MAXM-1;i>=0;--i){ if (dep[anc[u][i]]>=dep[v]) u=anc[u][i]; } if (u==v) return u; for (registerint i=MAXM-1;i>=0;--i){ if (anc[u][i]!=anc[v][i]) u=anc[u][i],v=anc[v][i]; } return anc[u][0]; } } usingnamespace L__C__A__Desu; structbuc{//更加好用的桶 int cnt[MAXN*2]; inlinevoidInit(){ memset(cnt,0,sizeof(cnt)); } int &operator [](int i){//重载运算符 return cnt[i+MAXN]; } }B; vector<int>Start[MAXN],End[MAXN],Lca[MAXN]; //以i为结束点的路线组成的集合为End[i] //.... //.... int dist[MAXN];//编号为i的路线的长度,即dist(s[i],t[i]) int ans[MAXN],w[MAXN]; int s[MAXN],t[MAXN]; voidSolve1(int u,int father){//统计上行路线的贡献 int temp=B[w[u]+dep[u]];//原来的已经有的(要减去) for (registerint i=0;i<G[u].size();++i){ int v=G[u][i]; if (v!=father) Solve1(v,u); } for (registerint i=0;i<Start[u].size();++i){ int id=Start[u][i]; B[dep[s[id]]]++; } ans[u]+=B[w[u]+dep[u]]-temp; for (registerint i=0;i<Lca[u].size();++i){ int id=Lca[u][i]; B[dep[s[id]]]--;//要减去,以后会完全包含于u的子树 } } voidSolve2(int u,int father){ int temp=B[dep[u]-w[u]]; for (registerint i=0;i<G[u].size();++i){ int v=G[u][i]; if (v!=father) Solve2(v,u); } for (registerint i=0;i<End[u].size();++i){ int id=End[u][i]; B[dep[t[id]]-dist[id]]++; } ans[u]+=B[dep[u]-w[u]]-temp; for (registerint i=0;i<Lca[u].size();++i){ int id=Lca[u][i]; B[dep[t[id]]-dist[id]]--; } } intmain(){ int n=read(),m=read(); for (registerint i=1;i<n;++i){ int u=read(),v=read(); AddEdge(u,v); AddEdge(v,u); } for (registerint i=1;i<=n;++i) w[i]=read(); dep[1]=1; dfs(1,1); for (registerint i=1;i<=m;++i){ s[i]=read(),t[i]=read(); int lca=LCA(s[i],t[i]); dist[i]=dep[s[i]]+dep[t[i]]-dep[lca]*2; Start[s[i]].push_back(i); End[t[i]].push_back(i); Lca[lca].push_back(i); if (dep[s[i]]-dep[lca]==w[lca]) ans[lca]--;//减去lca上面重复算的 } B.Init(),Solve1(1,1); B.Init(),Solve2(1,1); for (registerint i=1;i<=n;++i) printf("%d ",ans[i]); }
// luogu-judger-enable-o2 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define N 105 #define M 25005 usingnamespace std; int money[N],dp[M]; intmain(){ freopen("money.in","r",stdin); freopen("money.out","w",stdout); int t; scanf("%d",&t); while (t--){ memset(dp,0,sizeof(dp)); int n; scanf("%d",&n); for (registerint i=1;i<=n;++i){ scanf("%d",&money[i]); } int ans=0; sort(money+1,money+1+n); dp[0]=1; for (registerint i=1;i<=n;++i){ if (dp[money[i]]) { continue; } ans++; for (registerint j=money[i];j<=money[n];++j){//只用考虑大于当前数的 dp[j]|=dp[j-money[i]]; } } printf("%d\n",ans); } }