04 2018 档案
摘要:洛谷 3806 1 #include<cstdio> 2 #include<algorithm> 3 #define N 10010 4 #define rg register 5 using namespace std; 6 int n,m,tot,cnt,root,last[N],siz[N],
阅读全文
摘要:1 #include<cstdio> 2 #include<algorithm> 3 #include<queue> 4 #include<cstring> 5 #define N 1000010 6 #define rg register 7 using namespace std; 8 int
阅读全文
摘要:洛谷 3376 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #define N 10010 5 #define rg register 6 using namespace std; 7 int n,m,S,T,tot,
阅读全文
摘要:【题解】 二分图最大匹配的模板题。 1 #include<cstdio> 2 #include<algorithm> 3 #define N 1010 4 #define rg register 5 using namespace std; 6 int n,m,tot,ans,T,last[N],v
阅读全文
摘要:【题解】 贪心题。设五元组(mx,pos,l,r1,r2)表示最大值为mx,取得最大值的区间右端点为pos,区间左端点为l,区间右端点的可选区间为[r1,r2]. 每次从堆里拎出最大值,然后把这个区间拆了,因为选了[l,pos]这个区间之后就不能再选它了。我们得往堆了丢俩新的五元组(mx',pos'
阅读全文
摘要:【题解】 GDOI2016 Day2T3 如果给出的数据是一棵树那么皆大欢喜直接点分治就好了,用树状数组维护大于x的数的个数。如果是一棵基环树,我们先断掉环上的一条边,然后跑点分治;再加上经过这条边的方案数,其实就是从断掉的那条边的一个端点开始,把环遍历一遍,更新贡献的方式跟点分治过程中的差不多,具
阅读全文
摘要:【题解】 既然是一人对应一床,那么显然可以用二分图匹配来做。俩人认识的话,如果其中一个a是在校学生,另一个b不回家,b就可以向a的床连边(a,b当然也可以是同一个人)。 然后如果最大匹配数大于等于需要床的人数,就存在合法方案。 1 #include<cstdio> 2 #include<algori
阅读全文
摘要:【题解】 其实是个二分图最大匹配的模板题,直接上匈牙利算法就好了。 1 #include<cstdio> 2 #include<algorithm> 3 #define N 1010 4 #define rg register 5 using namespace std; 6 int n,m,E,a
阅读全文
摘要:【题解】 用线段树维护区间最大值(因为没有修改,St表也可以),然后由于x,y可能是降雨量未知的年份,需要进行分类讨论。 1 #include<cstdio> 2 #include<algorithm> 3 #define rg register 4 #define N 50010 5 #defin
阅读全文
摘要:【题解】 算是个思维题。。 题目数据范围很大,而是否能组成三角形这种信息也无法用数据结构维护,那怎么办呢? 我们可以发现,如果想要一个数列任意三项不能组成三角形且各项尽量小,这个数列就是一个斐波那契数列。而本题中点权范围为int范围内,我们可以发现在int范围内斐波那契数列只有46项。 那么如果给出
阅读全文
摘要:【题解】 二分答案。r要设好,不能随便设置为max(s,len),不然check的时候会爆long long 1 #include<cstdio> 2 #include<algorithm> 3 #define rg register 4 #define N 200010 5 #define LL
阅读全文
摘要:【题意概述】 给你N点M边的无向图(1<=N,M<=200000),一共删n次点, 每次询问删这个点之前是否完全联通。 【题解】 离线处理询问。倒着做就变成了加边加点,判断是否只有一个联通块。加入每个点now的时候先把cnt加1,然后遍历这个点连出去的边,发现to已经加入并且与now不在一个联通块里
阅读全文
摘要:【题解】 先跑一边最小生成树,记录树上最大的边权,然后对于每只猴子判断其跳跃距离是否大于等于最大边权即可。同时为了避免小数的麻烦,边权保留勾股定理后的平方结果,把猴子的跳跃距离平方一下,因为都是非负数,平方一下不改变大小关系。 1 #include<cstdio> 2 #include<algori
阅读全文
摘要:【题意概述】 给出一个有左括号和右括号的序列,左边的左括号和右边的右括号可以合并。现在要求你维护这个序列,支持两种操作: 1,翻转某个位置的括号; 2,查询区间[L,R]合并后第k个括号在原序列中的位置,如果k超过区间合并后的括号总数,输出-1. 【题解】 首先我们可以发现,对于一个区间,合并后的结
阅读全文
摘要:【题解】 套路题。。其实也很好想。。 把id为0的当成id为-1的,然后求前缀和,这样-1和1就可以相互抵消。也就是如果sum[i]=sum[j],那么x[i]-x[j+1]就是一个合法的答案。我们用first[i]记录满足sum[j]=i的j里面a[j+1]的最小值。 1 #include<cst
阅读全文
摘要:【题意概述】 K(1≤K≤100)只奶牛分散在N(1≤N≤1000)个牧场.现在她们要集中起来进餐.牧场之间有M(1≤M≤10000)条有向路连接,而且不存在起点和终点相同的有向路.她们进餐的地点必须是所有奶牛都可到达的地方.那么,有多少这样的牧场呢? 【题解】 一看题。。 对于每个点,把它能到达的
阅读全文
摘要:【题意概述】 数轴上有n个石子,第i个石头的坐标为Di,现在要从0跳到L,每次跳都从一个石子跳到相邻的下一个石子。现在FJ允许你移走M个石子,问移走这M个石子后,相邻两个石子距离的最小值的最大值是多少。 【题解】 二分答案(二分一个最小值)。check的时候判一下目前的距离是否大于等于mid,不满足
阅读全文
摘要:【题意概述】 给出100W个区间,要求找出尽量多的区间满足它们互补重叠,输出最大的区间数。 【题解】 贪心。 对区间按照右端点从小到大排序,然后逐个加入合法区间即可。 1 #include<cstdio> 2 #include<algorithm> 3 #define rg register 4 #
阅读全文
摘要:洛谷 1939 a[1]=a[2]=a[3]=1 a[x]=a[x-3]+a[x-1] (x>3) 求a数列的第n项对1000000007(10^9+7)取余的值。 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #def
阅读全文
摘要:洛谷 3390 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #define rg register 5 #define N 110 6 #define LL long long 7 using namespace st
阅读全文
摘要:【题解】 原来线段树还可以这么玩。。 我们用线段树维护连通性。对于一个矩形,我们用4个标记维护4个点的联通情况,再用两个标记维护右边两个点与它们右边的与它们在同一行的点的联通情况。 画图表示,就是 另一个关键问题是对于询问(r1,c1,r2,c2),并不是只可以走c1到c2之间的部分,它可以绕路走,
阅读全文
摘要:【题解】 用线段树维护即可。区间设为一个数以及询问区间的和。第二问的答案可以用砍掉的树的总数减去砍树区间覆盖的范围。 1 #include<cstdio> 2 #include<algorithm> 3 #define N 200010 4 #define rg register 5 #define
阅读全文
摘要:1 #include<cstdio> 2 #include<algorithm> 3 #define N 50010 4 #define M 500010 5 #define rg register 6 #define LL long long 7 using namespace std; 8 in
阅读全文
摘要:【题解】 维护乘法标记和加法标记的LCT 1 #include<cstdio> 2 #include<algorithm> 3 #define Mod (51061) 4 #define N 100010 5 #define rg register 6 #define ls (c[u][0]) 7
阅读全文
摘要:【题解】 我们把操作倒过来做,就变成了加边而不是删边。于是用LCT维护动态加边的最小生成树就好了。同样要注意把边权变为点权。 1 #include<cstdio> 2 #include<algorithm> 3 #define N 200010 4 #define rg register 5 #de
阅读全文
摘要:【题解】 很容易想到暴力做法,枚举每个点,然后对于每个点O(N)遍历整棵树计算答案。这样整个效率是O(N^2)的,显然不行。 我们考虑如果已知当前某个点的答案,如何快速计算它的儿子的答案。 显然选择它的儿子作为集合点,它的儿子的子树内的奶牛可以少走当前点到儿子节点的距离dis,不在它儿子的子树内的奶
阅读全文
摘要:【题解】 一头牛走到i,相当于把i点的子树的点权都加1,查询减慢的次数就是查询目的地的点权。 预处理dfs序,某个点的子树的dfs序是连续的一段。差分后用树状数组维护,变成点修区查。或者直接线段树区修点查。 1 #include<cstdio> 2 #include<algorithm> 3 #de
阅读全文
摘要:【题解】 很容易可以写出朴素DP方程f[i]=sigma f[j] (sum[i]>=sum[j],1<=j<=i). 于是我们用权值树状数组优化即可。 1 #include<cstdio> 2 #include<algorithm> 3 #define N 200010 4 #define rg
阅读全文
摘要:【题解】 贪心地选择子树内的节点,优先选代价小的。如果当前费用超出限制了就依次去掉当前费用最大的点,直到费用不超过限制。每个点的情况由它的孩子合并得到,所以要用到可并堆(左偏树)。 1 #include<cstdio> 2 #include<algorithm> 3 #define LL long
阅读全文
摘要:【题解】 蜜汁强制在线。。。 每个点开一个从它到根的可持久化权值线段树。查询的时候利用差分的思想在树上左右横跳就好了。 1 #include<cstdio> 2 #include<algorithm> 3 #define N 100010 4 #define rg register 5 #defin
阅读全文
摘要:【题解】 鲜活的水题。。我们把数列换成k进制的,发现数列是001,010,011,100,101,110,111...,而第m项用k进制表示的01串刚好就是m的二进制的01串。于是我们预处理k的幂,把n化成2进制的,在用这个01串求数列第n项即可。 1 #include<cstdio> 2 #inc
阅读全文
摘要:【题解】 明显的LCT模板题,c种颜色就开c棵LCT好了。。 1 #include<cstdio> 2 #include<algorithm> 3 #define N 100010 4 #define C 11 5 #define rg register 6 #define ls (son[c][u
阅读全文
摘要:【题解】 一眼可以想到一个类似二叉树后序遍历的贪心做法,然而这个做法在有相同数字的情况下是错误的。最简单的反例就是n=4,d={1,1,1,2},正解是1,1,2,1,而贪心是1,1,1,2. 所以这个贪心被叉掉了。 我们先把d从大到小排序,然后我们用f[i]表示第i个位置之前(包括i位置)还能取的
阅读全文
摘要:【题解】 这道题其实有个树状数组维护dfs序的做法,不过懒得想那么多直接写了Link-Cut Tree 1 #include<cstdio> 2 #include<algorithm> 3 #define N 600010 4 #define rg register 5 #define ls (c[
阅读全文
摘要:【题解】 先把区间按照未离散化的长度排序,保存区间长度,然后离散化区间端点。每次把区间覆盖的点的覆盖次数加1,如果某个点被覆盖次数大于等于m,就从前往后开始删除区间直到没有一个点被覆盖的次数大于等于m,然后继续加入区间。边做边维护答案即可。 1 #include<cstdio> 2 #include
阅读全文
摘要:【题解】 第一眼看题飞快地想到一种做法,然后假掉了。 这道题其实是主席树的模板题来着。但是也有别的水法。 我们可以发现每个位置的查询区间是[1,min(a[i],i-1)],所以我们可以把查询区间按照右端点排序。开一个权值树状数组记录前i个a[i]的出现情况。我们从1到n按顺序插入a[i],每个位置
阅读全文
摘要:【题意概述】 给出平面上的10W个点,要求判断这些点能否被两条直线穿过,即一个点至少在一条直线上。 【题解】 思路很快可以想到。取3个不共线的点,它们形成一个三角形;如果有解,其中的一条直线一定与三角形的一条边重合。于是用这三条边一一进行验证即可。 第一次交被卡了精度,后来意识到判断三个点是否共线写
阅读全文
摘要:50%的数据满足:1 <= k <= 5, 1 <= ci <= 3 100%的数据满足:1 <= k <= 15, 1 <= ci <= 5 【题解】 本题中ci很小,因此可以直接5维保存可以涂i块的油漆有多少种颜色。然后利用乘法原理进行DP 1 #include<cstdio> 2 #inclu
阅读全文
摘要:【题解】 二分答案+二分图匹配。 先二分最小值Min,然后扫一遍这个矩阵,把满足a[i][j]<=Min的i,j连边,之后跑二分图匹配,如果最大匹配数大于等于n-k+1,当前的Min即是合法的。题目中要求选出的数不能在同一行或者同一列,而这种行与列连边跑二分图的做法就保证了一行与一列对应,最多只能选
阅读全文
摘要:【题解】 给出一条路径,问树上的点被经过了几次。 显然树剖之后树上差分就好了。 1 #include<cstdio> 2 #include<algorithm> 3 #define N 300010 4 #define rg register 5 using namespace std; 6 int
阅读全文
摘要:【题解】 我们可以轻松想到朴素的状态转移方程,但直接这样做是n^2的。所以我们考虑采用树状数组优化。写法跟求逆序对很相似,即对前缀和离散化之后开一个权值树状数组,每次f[i]+=query(sum[i]),再把f[i]加入到sum[i]位置上。这样可以保证每次f[i]加上的是在它前面的、sum小于它
阅读全文
摘要:【题解】 每个情报员的危险值val[i]应该是一个分段函数,前面一段是平行于x轴的横线,后面一段是一次函数。我们可以用fx(t)=t-b[x]表示这个一次函数。每次询问一条链上fx(t)大于c的点的个数,也就是问有多少个点满足t-b[x]>c,移项得b[x]<t-c,不等式左边只与点有关,可以当做点
阅读全文
摘要:【题解】 因为这道题中n比较小,n^2效率是可以接受的。 枚举两个矩形,如果它们有重叠部分,就用并查集合并一下即可。 1 #include<cstdio> 2 #include<algorithm> 3 #define N 8000 4 #define rg register 5 using nam
阅读全文
摘要:【题解】 n^6的做法很好想,然而这样复杂度不对。。 然后我们可以发现R和C可以分开求,这样复杂度降到了n^4. 使用树状数组可以把复杂度降到n^3logn,可以顺利通过。 1 #include<cstdio> 2 #include<algorithm> 3 #define N 1010 4 #de
阅读全文
摘要:【题解】 烧开每一杯水之后都用它去把其他没烧开的水焐热,这样显然是最优的。然后推推式子或者列表找规律就好了。 1 #include<cstdio> 2 #include<algorithm> 3 #define rg register 4 using namespace std; 5 int n;
阅读全文
摘要:【题解】 鲜活的大水题。。。 把区间排个序然后瞎搞就可以了,发现现在区间的左端点比之前区间的最大的右端点还大,那就增加一个答案区间。每次更新目前最大右区间。 1 #include<cstdio> 2 #include<algorithm> 3 #define N 200010 4 #define r
阅读全文
摘要:【题解】 直接把松弛操作中dis[to]=dis[now]+e[i].dis改成dis[to]=dis[now]*e[i].dis是不行的,因为这样做会爆long long. 同时也可以发现在最短路中我们并不能边松弛边取模,这会导致答案错误。 其实我们可以把边权取个log. 因为log(M*N)=l
阅读全文