摘要: 首先考虑猪无法流动,那么源点向每一个猪圈连猪圈中猪个数的边,每一个顾客向汇点连所需猪的边,每一个猪圈向能打开它的顾客连inf的边,跑最大流即可。 但考虑猪要流动,有一个十分巧妙地做法,将每一个顾客所有有公共猪圈的顾客连inf的边,同时每一个猪圈只连向第一次打开它的顾客(也可以流向所有顾客,不过没必要 阅读全文
posted @ 2019-07-28 10:44 PYWBKTDA 阅读(103) 评论(0) 推荐(0) 编辑
摘要: 题意是需要在某些相邻的节点中建立栅栏使得这两个点不能直接走到,使得所有狼的领地和羊的领地两两不能(间接)走到最少需要多少栅栏。 很显然,将S向所有羊连边,狼向T连边(流量为inf),然后任意相邻两个点连边(羊/狼之间可以不连),求最小割即可。 1 #include<bits/stdc++.h> 2 阅读全文
posted @ 2019-07-28 10:44 PYWBKTDA 阅读(181) 评论(0) 推荐(0) 编辑
摘要: 将原图黑白染色,然后白点放左边,黑点放右边,原点向白点连点权的边,汇点向黑点连点权的边,白点向相邻黑点流inf的边,求最小割,用总权值减掉最小割即可。这样每相邻两个点一定有一个点的边被割掉,最小割就是最小的去掉的点,剩下的就是最大值了。 1 #include<bits/stdc++.h> 2 usi 阅读全文
posted @ 2019-07-28 10:44 PYWBKTDA 阅读(149) 评论(0) 推荐(0) 编辑
摘要: 由于无法直接将果汁和饮料连边,所以将人放在中间,果汁和饮料放在两侧,然后分别向对应的人连边。同时,为了保证每一个人只被算一次,对每一个人裂点,两个点中间连一条流量为1的边。 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 50 阅读全文
posted @ 2019-07-28 10:43 PYWBKTDA 阅读(104) 评论(0) 推荐(0) 编辑
摘要: 对于每一个颜色用一个链表存储,并记录下:1.当前某种颜色的真实颜色;2.这种颜色的数量(用于启发式合并的判断);3.当前答案(即有几段),然后对于每一个操作简单处理一下就行了。 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 阅读全文
posted @ 2019-07-28 10:43 PYWBKTDA 阅读(103) 评论(0) 推荐(0) 编辑
摘要: 先建立最短路径树(即跑dij每一个点向更新他的点连边),考虑一个点的答案路径一定要走过且仅走过一条非树边,枚举非树边(x,y),对于一个点k,如果它在x~lca上(y~lca的路径上同理),那么答案可以更改为s[y]+len(x,y)+s[x]-s[k],前三个不受k的影响,因此越小越好,即将每一条 阅读全文
posted @ 2019-07-28 10:43 PYWBKTDA 阅读(194) 评论(0) 推荐(0) 编辑
摘要: 考虑木板一定都尽量长,对于每一个污泥,最多只有两种木板会覆盖它(横着和竖的),将这两块木板连边,意味着每一条边两端端点中一定有一个点要被选,即最小点覆盖=最大匹配数。 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 105 4 阅读全文
posted @ 2019-07-28 10:42 PYWBKTDA 阅读(164) 评论(0) 推荐(0) 编辑
摘要: 将每一行/每一列作为一个点,对于一个障碍(x,y),要么第x行和第y列的状态(是否攻击)只需要有一个就可以了,将第x行和第y列连边,就是二分图的最小点覆盖=最大匹配数。 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 1005 阅读全文
posted @ 2019-07-28 10:42 PYWBKTDA 阅读(231) 评论(0) 推荐(0) 编辑
摘要: 二分答案,每一头牛向所有在规定时间内能走到的牛棚连inf的边,每一个源点向牛连牛数量的边,每一个牛棚向汇点连牛棚容量的边,能满流则意味着这个答案可行,否则不可行。 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 505 4 # 阅读全文
posted @ 2019-07-28 10:42 PYWBKTDA 阅读(116) 评论(0) 推荐(0) 编辑
摘要: 同poj1741一样,只是将统计每一个点的深度改为深度除以3余数为0、1和2的点数量,注意(1,2)和(2,1)算两种。 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 #de 阅读全文
posted @ 2019-07-28 10:41 PYWBKTDA 阅读(120) 评论(0) 推荐(0) 编辑
摘要: 同[bzoj3894]文理分科,只是将五个点一组改为2个点一组(另外还可以通过解方程优化建边,但这里不需要)。 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 60005 4 #define id (i-1)*m+j 5 #d 阅读全文
posted @ 2019-07-28 10:41 PYWBKTDA 阅读(92) 评论(0) 推荐(0) 编辑
摘要: 由于k较小,因此考虑不断选取最大值,但同时还要删掉最大值。记f(k,l,r)表示以k为右端点时左端点在l~r之间的最大值,这个可以用线段树快速求出。当发现最大值是f(k,l,r)时,假设在位置t取到,则删除f(k,l,r)并加入f(k,l,t-1)和f(k,t+1,r),这个可以用堆来维护。初始时加 阅读全文
posted @ 2019-07-28 10:41 PYWBKTDA 阅读(96) 评论(0) 推荐(0) 编辑
摘要: 对于三个点x、y和z,设a=lca(x,y),b=lca(x,z),不妨假设a的深度比b大,则b是a的祖先(因为a是x的祖先,b也是x的祖先)。 首先将集合点定在a,考虑a向每一个方向调整,a向父亲调整会让x和y答案加一,a向靠近x(y同理)的儿子调整,会让y和z答案加一,向其他儿子调整,会让三者答 阅读全文
posted @ 2019-07-28 10:41 PYWBKTDA 阅读(176) 评论(0) 推荐(0) 编辑
摘要: 初始对于每一个叶子节点建一棵权值线段树,然后再线段树合并时计算一下两者分别在前面和后面的代价,$ans+=min(\sum sz[rz[x]]\cdot sz[ls[y]],\sum sz[ls[x]]\cdot sz[rs[y]])$ 1 #include<bits/stdc++.h> 2 usi 阅读全文
posted @ 2019-07-28 10:40 PYWBKTDA 阅读(136) 评论(0) 推荐(0) 编辑
摘要: 同[bzoj1101]Zap,容斥即可。 1 #include<bits/stdc++.h> 2 using namespace std; 3 int t,a,b,c,d,k,f[50005],vis[100005],p[50005]; 4 void mobies(int n){ 5 memset( 阅读全文
posted @ 2019-07-28 10:40 PYWBKTDA 阅读(101) 评论(0) 推荐(0) 编辑
摘要: 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define mod 100000009 5 #define N 10000005 6 ll t,n,m,ans,c[N],f[N],vis[N],p 阅读全文
posted @ 2019-07-28 10:39 PYWBKTDA 阅读(116) 评论(0) 推荐(0) 编辑
摘要: 根据每一个点到根的每一个点的权值建立n颗权值线段树(也就是一颗可持久化线段树/主席树),然后查询操作相当于对F[x]+F[y]-F[lca(x,y)]-F[fa[lca(x,y)]]这颗线段树作查询。 1 #include<bits/stdc++.h> 2 using namespace std; 阅读全文
posted @ 2019-07-28 10:39 PYWBKTDA 阅读(97) 评论(0) 推荐(0) 编辑
摘要: 考虑一条边被选入最小生成树的条件,即所有比他小的边不能让这条边所连接的两个点连通,那么将所有边建成两条有向边并跑这两个点的最小割即可(最大生成树同理,但不可以一起做)。 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 2000 阅读全文
posted @ 2019-07-28 10:39 PYWBKTDA 阅读(92) 评论(0) 推荐(0) 编辑
摘要: 首先肯定每一位单独考虑,对于每一位,源点连向该位点权为0的节点inf的边,点权为1的节点连向汇点inf的边,每一条无向边拆成两条流量为1的有向边,跑最小割。 考虑一组割,一定将原图划分成源点和汇点两部分,那么左半部分都选0,右半部分都选1,那么它的代价就是割的代价,即要求最小割。 为了让点的值最小, 阅读全文
posted @ 2019-07-28 10:39 PYWBKTDA 阅读(182) 评论(0) 推荐(0) 编辑
摘要: 如果没有换根操作,可以直接用树剖维护,考虑修改操作与根无关,所以只需要特殊处理查询操作。 对于查询操作,假设查询点为x,初始的根是1,实际的根是r,一共要分三种情况来考虑:1. 若lca(r,x)!=x或x=r,则直接对以x为根的子树查询即可; 2. 若lca(r,x)=x且x!=r,则对整棵树除了 阅读全文
posted @ 2019-07-28 10:38 PYWBKTDA 阅读(99) 评论(0) 推荐(0) 编辑
摘要: 以x和y作为坐标建立kdtree,然后维护某一棵子树内的美味值之和,如果同一颗子树的四个角的甜味都小于h,那么就可以直接累加进去。虽然这样的最坏时间复杂度仍然是$o(n^{2})$,但可以卡过去。 1 #include<bits/stdc++.h> 2 using namespace std; 3 阅读全文
posted @ 2019-07-28 10:38 PYWBKTDA 阅读(118) 评论(0) 推荐(0) 编辑
摘要: 预处理出每一个点下一个相同颜色的位置,记为next,然后将询问按左端点排序后不断右移左指针,设要删除i位置,就令f[next[next[i]]+1,同时还要删除原来的标记,即令f[next[i]]-1,最后即询问$\sum_{i=1}^{r}f[i]$,线段树维护即可。 1 #include<bit 阅读全文
posted @ 2019-07-28 10:38 PYWBKTDA 阅读(113) 评论(0) 推荐(0) 编辑
摘要: 对于前两个sigma,可以直接处理,相当于求$\sum\limits_{1\leq i<j\leq n}lcp(i,j)$ 。 倒序字符串后的parent树(后缀树),lcp(i,j)其实就是i这个前缀和j这个前缀parent树上的lca,则对于任意一个节点,考虑其为lca的方案,就是任意两个儿子中 阅读全文
posted @ 2019-07-28 10:38 PYWBKTDA 阅读(108) 评论(0) 推荐(0) 编辑
摘要: 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 10000001 4 int t,n,m,k,mu[N],vis[N],p[N]; 5 long long ans,f[N]; 6 void linear(){ 7 mu[1]= 阅读全文
posted @ 2019-07-28 10:38 PYWBKTDA 阅读(69) 评论(0) 推荐(0) 编辑
摘要: 首先对于询问操作可以使用可持久化线段树来维护,对于连边操作对于两颗树中选取较小的树暴力练到另一个点上,点数可以用并查集然后只修改根的点数即可。 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define mid (l+r>>1) 4 #def 阅读全文
posted @ 2019-07-28 10:38 PYWBKTDA 阅读(155) 评论(0) 推荐(0) 编辑