[亂搞]JZOJ 5913 林下風氣
阿新 • • 發佈:2018-10-19
clu 存在 ios opened int 相減 bec long printf
分析
我們把差值小於等於k的方案數和插值小於k的方案數相減就是等於k的方案數嘛
然後我們每次對以i為根的子樹求方案數,但是有問題:如果值相等,可能會算多次,所以我們只算比編號根大的點,就避免了重復。
#include <iostream> #include <cstdio> using namespace std; const int N=3333+10; const int P=19260817; struct Edge { int u,v,nx; }g[2*N]; int cnt,list[N]; int w[N]; int n,k; void Add(int u,int v) { g[++cnt].u=u;g[cnt].v=v;g[cnt].nx=list[u];list[u]=cnt; } intView CodeDfs(int u,int fa,int mxid) { long long ans=1; for (int i=list[u];i;i=g[i].nx) if (g[i].v!=fa&&w[mxid]>=w[g[i].v]&&w[mxid]-w[g[i].v]<=k&&(mxid<g[i].v||w[mxid]!=w[g[i].v])) (ans*=1ll*Dfs(g[i].v,u,mxid)+1)%=P; return ans; } int main() { freopen("lkf.in","r",stdin); freopen("lkf.out","w",stdout); scanf("%d%d",&n,&k); for (int i=1;i<=n;i++) scanf("%d",&w[i]); for (int i=1;i<n;i++) { int u,v; scanf("%d%d",&u,&v); Add(u,v);Add(v,u); } int smaller_or_equals_k=0,smaller_or_equals_k_1=0; for (int i=1;i<=n;i++) (smaller_or_equals_k+=Dfs(i,-1,i))%=P; if (k) { k--; for (int i=1;i<=n;i++) (smaller_or_equals_k_1+=Dfs(i,-1,i))%=P; } printf("%d",(smaller_or_equals_k-smaller_or_equals_k_1+P)%P); }
[亂搞]JZOJ 5913 林下風氣