摘要:
用f[i][j]表示完成前i个任务,在A机器上加工j小时时B机器上最少要工作多小时,转移就分为三种,即$f[i][j]=min(f[i-1][j-t1],f[i-1][j]+t2,f[i-t3]+t3)$,然后这个东西可以用类似于背包的方式优化到1维(注意要从大到小枚举) 1 #include<bi 阅读全文
摘要:
先考虑如何判定一个r*c的矩阵是否符合条件,容易发现左上角的点无法被别的矩阵砸到,要求左上角r*c的矩阵中不能超过最左上角的元素,之后同理不断枚举最上&最左的非0点,可以用差分来优化,复杂度为$o(n^{4})$(n和m同阶)(然后加上一些整除、倒序枚举的剪枝就可以过了)正解是这样的,枚举1*c的最 阅读全文
摘要:
先求出任意一棵最小生成树,然后对边分类讨论1.非树边,答案即最小生成树的环上的最长边2.树边,反过来考虑,相当于对于每一个点对那条路经打上标记,取min对于1直接用倍增维护即可,对于2可以用树链剖分/差分+启发式合并但都需要两个log,所以有一种很神奇的做法考虑从小到大枚举非树边,然后暴力修改,容易 阅读全文
摘要:
首先用到bzoj2456的做法,因为要求这个数出现次数超过了一半,如果其与不同的数两两相消的话最终一定会剩下自身(如果不保证存在可能会剩下别的,但保证存在了只会剩下自身),然后再用可持久化线段树维护即可 1 #include<bits/stdc++.h> 2 using namespace std; 阅读全文
摘要:
观察样例,令f(n)表示n拆分的答案,猜想$f(n)=3f(n-3)$,当$n\le 4$时$f(n)=n$取3的原因是因为对于给定的$x+y$,当$4<x+y$,显然有$3^{x+y-3}$最大,否则直接取$x+y$即为最大值,也就是给出的递推式 1 #include<bits/stdc++.h> 阅读全文
摘要:
如果把这个矩阵看成一张图,题目相当于要求每一个点的入度和出度都是1(也就是有很多环),否则指向环的点就无法走回自己了将所有点拆成两个,S向原来的点流(1,0)的边,拆出来的点向T连(1,0)的边,然后每一个点指向初始方向上的点(1,0)的边,指向非初始方向上(1,1)的边,求最小费用最大流即可(也就 阅读全文
摘要:
用一种类似于hash的做法(就是比较假可能会被卡的做法),维护区间最小值、最大值和区间和,根据这些信息来判断是否矛盾即可当然还有比较严谨的方法,维护区间min、区间max、区间相邻两数的gcd和区间pre的max,这样就可以保证答案的正确性 1 #include<bits/stdc++.h> 2 u 阅读全文
摘要:
kruskal重构树,求出最小生成树,然后不断加边并新建节点作为两个联通块原根节点的父亲节点并作为新联通块的根(类似于不路径压缩的并查集),这样一来满足每一个节点所代表的边(除叶子节点外)父亲总时比儿子大,因此询问即在该重构树上的某一段点的第K大,用可持久化线段树维护,同时还要用倍增来确定该段的根节 阅读全文
摘要:
对每一个节点开一颗权值线段树维护打的标记(x+,y+,lca(x,y)-,fa[lca(x,y)]-),然后每一个节点将子树内所有节点(其实就是已经合并过的儿子)合并即可。(毒瘤的是这道题需要将物品离散化一下否则会爆栈,当然也可以写bfs) 1 # pragma comment(linker, /S 阅读全文
摘要:
对棋盘黑白染色后,若n和m都是奇数(即白色和黑色点数不同),可以直接算得答案(根据白-黑不变);若n和m不都是奇数,二分答案(二分的上限要大一点,开$2^50$),最后都要用用网络流来判定。考虑判定,将白色点放在左边,黑色点放在右边,源点流向白点的流量是白点与答案的差,黑点流向汇点的流量是黑点与答案 阅读全文
摘要:
二分图的充要条件是存在奇环,对其线段树分治,用按秩合并并查集维护即可(注意自环) 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 200005 4 #define L (k<<1) 5 #define R (L+1) 6 #d 阅读全文
摘要:
容易发现a2一定是分母,且容易做到其余都是分子,因此相当于判定a2能否整除a1*a3*……*an,不断让a2除以其与其他数的gcd即可(注意特判n=1) 1 #include<bits/stdc++.h> 2 using namespace std; 3 int t,n,s,x; 4 int gcd 阅读全文
摘要:
首先发现当n堆石子可以两两配对时,后手必胜,因为后手可以模仿先手那么当n堆石子不能两两配对时,先手必胜,因为先手可以做到让其两两配对,然后即先手必胜 这个东西用map维护即可 1 #include<bits/stdc++.h> 2 using namespace std; 3 map<int,int 阅读全文
摘要:
考虑最坏的做法,就是将所有集合合并起来再拆开,需要n+m-2次当两个的某一个子集和相同时,这个子集和单独处理,不与整体合并,可以减少2次那么题目转化为询问有最多能选出多少个不相交的子集对,满足子集和相同状压dp,用f[S1][S2]表示从S1和S2中选,那么分为两种情况考虑:1.S1的和等于S2的和 阅读全文
摘要:
考虑如果没有k个人,那么就是裸的二分答案+最大流对于这k个人,再在原来的每一个点裂点,中间的流量为k,然后裂出来的点向所有不能匹配的点连边,再二分答案+最大流即可 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 205 4 s 阅读全文
摘要:
容易发现所有豆子相互独立,只需要考虑每一个豆子的sg函数并异或起来即可,sg函数从后往前暴力即可 1 #include<bits/stdc++.h> 2 using namespace std; 3 int t,n,x,y,z,s,ans,a[105],sg[105],vis[105]; 4 int 阅读全文
摘要:
为了方便考虑,不妨规定只有当当前的巧克力棒都取完了,才能拿新的巧克力棒然后令先手第一个拿的集合为S,根据nim游戏,当S的xor不为0时先手(即原来的后手)必胜,又轮到先手拿集合,那么只要一直不存在xor为0的集合,先手最终就必败然后当存在xor为0的集合,那么先手必然可以做到取一个最大xor子集, 阅读全文
摘要:
将每一个点拆成500个点,表示分别表示以某个速度到这里时的最短路,然后跑最短路即可,注意距离是double类型 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 205 4 struct ji{ 5 int nex,to,len 阅读全文
摘要:
对于所有限制,都可以写成形如$di>=dj+c$的形式(等式看成两个),然后这个东西很显然就是一张图的一条边,然后求最长路即可(当c为负移项即可)由于每一个人都要有糖,所以让di初始为1并入队即可(注意:最好判掉自环,可以快很多,如果不判在spfa时应将标记清空放在前面,否则就找不到自环了) 1 # 阅读全文
摘要:
很显然是网络流,对于点的限制,拆点建流量为1的边,之后跑最小费用最大流即可(由此很显然可以发现原图边的流量也只需要1) 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 405 4 struct ji{ 5 int nex,to 阅读全文
摘要:
第一问直接最大流即可,记这个最大流为ans第二问可以在原图的基础上,初始边费用为0,新增费用为w流量为inf的边,新增0号点向1流一条流量为ans+k,费用为0的边,跑最小费用最大流即可考虑这个过程中,由于费用都为正,所以一定先走费用为0的边,相当于现求最大流,所以可以直接在残余网络上加入费用为w, 阅读全文
摘要:
最小割,考虑最小割就是要将整张图分为两块,本题中就分别表示赞同和不赞同,那么首先一开始赞同的点向S连边,不赞同的点向T连边,如果这些点分到了另一边就要割掉这条边,朋友关系同理,连双向边同样表示分到两边要割掉这条边,跑最小割=最大流即可 1 #include<bits/stdc++.h> 2 usin 阅读全文
摘要:
考虑每一个位置最多开6次左右就会变成1,然后操作就没有意义了,因此对线段树维护区间和和一个标记,表示是否全部都是1,然后对于修改,如果区间标记不是1就暴力下去,是1就不用操作,复杂度为$o(6nlogn)$ 1 #include<bits/stdc++.h> 2 using namespace st 阅读全文
摘要:
记si表示前缀和,由于账本可以为负,所以si本身是没有限制的,然后每一条消息相当于让某两天的差值确定,连一条边,之后在每一次消息中,先判断两点是否连通,连通就直接判断,不连通就加上这条边即可,这个东西可以用带权的并查集来维护 1 #include<bits/stdc++.h> 2 using nam 阅读全文
摘要:
将问题和锦囊二分图匹配即可,注意当某一个不合法就要退出 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 2005 4 struct ji{ 5 int nex,to; 6 }edge[N]; 7 int E,n,m,x,y,a 阅读全文