摘要: 思路:首先这道题可以直接裸上树剖。 然后参见了黄学长的博客发现了一种更为高明的解法,可以在树上差分,令x为路径(u,v)的lca,然后f[u]++,f[v]++,f[x]--,f[fa[x]]--,然后直接一遍dfs累加起来就好了。(为什么我的代码常数辣么大。。。差分被树剖虐。。。。) 阅读全文
posted @ 2016-10-23 20:00 DUXT 阅读(163) 评论(0) 推荐(0) 编辑
摘要: 思路:首先先求出以1为根的答案,然后考虑由i转移到i的儿子的答案的变化,显然以son[i]为根的子树的所有结点的深度都会减一,其余的点的深度都会加一,然后就可以直接O(n)求出所有结点的答案,然后取max更新答案即可。 #include<iostream> #include<cstdio> #inc 阅读全文
posted @ 2016-10-23 19:55 DUXT 阅读(172) 评论(0) 推荐(0) 编辑
摘要: 思路:状压dp,设f[i][j]表示当前已经选出的牛的状态为i,最后一头选出的牛为j的方案数。 然后注意就是初值不能是f[0][i]=1,因为所有牛本来都可以第一个被选中,然而这样一定初值有些牛可能就无法被第一个选出了,因此应该是f[(1<<i)][i]=1。 #include<iostream> 阅读全文
posted @ 2016-10-23 19:51 DUXT 阅读(221) 评论(0) 推荐(0) 编辑
摘要: 思路:状压dp,枚举疾病的集合,然后判断一下可行性即可。 #include<bits/stdc++.h> using namespace std; #define maxs 400000 #define maxn 1900 int n,d,k; int a[maxn],f[maxs],num[max 阅读全文
posted @ 2016-10-23 19:47 DUXT 阅读(238) 评论(0) 推荐(0) 编辑
摘要: 思路:状压dp,f[i][j]表示新的排列的状态为i(也就是新的排列已经选了哪些数),然后模d的余数为j的方案数。 但考虑到可能有些数会出现多次,假设一个数x出现了cnt[x]次,那么对于一个可行的答案,显然也包含cnt[x]个x,那么这样的答案就会被计算多次,因为如果状态i先加入第一个x再加入第二 阅读全文
posted @ 2016-10-23 19:44 DUXT 阅读(313) 评论(0) 推荐(0) 编辑
摘要: 思路:看到n十分于是考虑状压dp,先预处理出处于状态s的情况下过桥的时间和重量,然后枚举状态转移即可,f[i]=min(f[i],f[j]+time[i^j])(j∈i)(自称会状压dp结果连枚举非空子集都不会的我。。。。。) 顺便普及如何枚举非空子集:for (int j=i;j;j=j&(i-1 阅读全文
posted @ 2016-10-23 19:33 DUXT 阅读(188) 评论(0) 推荐(0) 编辑