自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

Lynstery's blog

Think twice and code once.

  • 博客(84)
  • 收藏
  • 关注

原创 [DP] BZOJ2660: [Beijing wc2012]最多的方案

好题。fibfib 数不多,先都直接得到。注意到 fibfib 相邻数可以合并,所以我们就贪心的求出数最大的一组解,然后考虑把取来的数分裂。 设我们现在有一个fibifib_i,他能分裂成什么样呢? fibi=fibi−1+fibi−2=fibi−1+fibi−3+fibi−4=fibi−1+fibi−3+fibi−5+fibi−6fib_i=fib_{i-1}+fib_{i-2}=fib_{

2017-10-31 22:25:41 306

原创 [博弈 DP] BZOJ1783: [Usaco2010 Jan]Taking Turns

这个博弈比较简单,每个人的目标仅仅是让自己的分多。所以直接 DPDP 求: 设 fi,0f_{i,0} 表示 从 ii 开始取,先手最优值。fi,1f_{i,1} 是后手的最优值。 显然有 fi,0=max{aj+fj+1,1}f_{i,0}=max\{a_j+f_{j+1,1}\},fi,1=fpos,0f_{i,1}=f_{pos,0}。pospos 表示 fi,0f_{i,0} 是从哪里转

2017-10-31 16:26:19 403

原创 [杂题 异或 带权并查集] BZOJ2303: [Apio2011]方格染色

不太容易想到。首先要把限制看成异或,即每个点都要满足 ai,j xor ai,j−1 xor ai−1,j xor ai−1,j−1=1a_{i,j}\text{ xor }a_{i,j-1}\text{ xor }a_{i-1,j}\text{ xor }a_{i-1,j-1}=1 这些限制太复杂了,怎么进行转化呢? 注意到,如果我们已经确定的第一行和第一列的所有元素,则其他也确定了。所以

2017-10-31 14:16:39 400

原创 [递推] BZOJ2173:整数的lqp拆分

简单题。考虑每个 fibifib_i 的贡献可得: fi=∑i=1nfibi∗fn−if_i=\sum_{i=1}^n fib_i*f_{n-i} 和斐波那契数有关,肯定考虑递推。然 xjbxjb 推就行了: fi=fn−1+∑i=2nfibi∗fn−i=∑i=2nfibi−1∗fn−i+∑i=2nfibi−2∗fn−1=fn−1+fn−1+fn−2f_i=f_{n-1}+\sum_{i

2017-10-31 09:12:59 376

原创 [DP] HHHOJ #115. 我们爱数数

其实当时已经几乎想到了,但是没发现答案已经求好了…… 大概的思路是,这种至少 KK 的问题时,一般不能直接求出答案而要进行一些加加减减。就考虑 DPDP 求出一些东西。 注意到如果不放在快乐的位置的人,如果要选个位置放下的话必须要 2n2^n 记下状态。规模不能承受。 所以我们干脆让不快乐的随便填,即只考虑填快乐的,剩下的全排列。 这样只需要记前两个位置是否被占,就可以做到 O(n2)O(n

2017-10-30 21:17:32 620

原创 [杂题 离散 扫描线] BZOJ1227: [SDOI2009]虔诚的墓主人

不难的题。 考虑一个空的点的贡献是一个组合数的形式,即答案为 ∑(leftK)(rightK)(upK)(downK) \sum {left \choose K }{right \choose K }{up \choose K }{down \choose K } 怎么求呢? 显然先离散,只需考虑离散后的网格上的点。 对于每一行,可以考虑扫过取求两个实点中间空点的贡献,每一段的贡献是(le

2017-10-30 18:43:59 308

原创 [杂题 树状数组] 51Nod1681 公共祖先

不错的题,思路很套路。考虑求的答案是 ∑i,j∑k[k在两棵树中都是i,j的祖先]\sum_{i,j} \sum_k [k在两棵树中都是i,j的祖先] 改变枚举顺序,设 Son1(x)Son_1(x) 表示第一棵树中以x为根的子树的点集,答案就变成: ∑k(|Son1(k)∩Son2(k)|2)\sum_k { | Son_1(k) \cap Son_2(k) |\choose 2} 这个

2017-10-30 07:47:34 350

原创 [贪心+堆+链表] 51Nod1053 最大M子段和 V2

这里用到了把某些东西缩到一起的重要思想,可能能简化问题。在今后的数据结构题中可能会用到较多。 对于这题,可以把连续的同号元素缩到一起。如果把所有正段取完肯定是最好的,但是可能会超出段的限制。于是考虑牺牲总价值来减小段数。这也是个比较经典的思路。 减小有两种,删去正段,或把相邻正段合并,中间多取一个负段。

2017-10-29 21:17:34 415

原创 [杂题 贪心] BZOJ4723: [POI2017]Flappy Bird

本来想倒着搞得到每个点的柱子能飞的区间,但是发现飞的位置和横坐标奇偶性有关,不太对。 其实正着搞就好了,每次得到的区间,由于奇偶的原因需要微调。#include<cstdio>#include<algorithm>using namespace std;const int maxn=500005;int n,x[maxn],a[maxn],b[maxn],now_L,now_R;int

2017-10-29 20:43:47 399

原创 [枚举+三分] Codeforces #626E. Simple Skewness

容易想到排序后枚举中位数,然后相当于两边取相同个数的数。我们想让平均数更大,肯定贪心的取后面一段的和。 注意到这种排序之后的前缀和是一个上凸的函数,并且再除以一个不断变大的数,yy一下发现是单峰的,直接3分就好了。#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int maxn=50

2017-10-29 20:29:45 427

原创 [杂题] BZOJ3522: [Poi2014]Hotel

这题不要想的太复杂,要暴力一点。不需要定树根搞,如果是有根树的话,发现沿父边往上走的点很难统计。 所以就直接枚举中间点,把他作为根,相当于求在不同子树中选 33 个深度相同的点的方案数。直接暴力便利一遍图,统计一下就好了。#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long

2017-10-27 14:15:18 296

原创 [KMP] Codeforces #631D. Messenger

首先要把相同的缩到一起,然后考虑就是一个简单的匹配。 注意到b串两端的字符在a串里匹配可能比a串里那一块少。解决办法就是先把b的两端扣掉匹配,每次匹配成功时判断一下就好了。#include<cstdio>#include<algorithm>#define Fir first#define Sec second#define mp(x,y) make_pair(x,y)using nam

2017-10-26 16:40:16 349

原创 [杂题] Codeforces #632D Longest Subsequence

值的范围是10610^6 ,所以可以想到直接枚举公倍数。然后就是要统计一个数的因数出现了几个。这个直接 O(nlogn)O(n\log n) 。 实际上这题有一个条件弱化的思想,不需要一定是最小公倍数,大的公倍数满足,对应的最小公倍数也满足。#include<cstdio>#include<algorithm>using namespace std;const int maxn=100000

2017-10-26 15:20:15 249

原创 边双连通分量——学习(复习)笔记

一年前学过边双,而然一直没怎么用过,忘完了(我真是菜),来补一发。一些概念如果任意两点至少存在两条边不重复路径,则称该图为边双连通的 边双连通的极大子图称为边双连通分量 桥是指当删去这个边时,连通块的数量会增加 边双连通分量中不存在桥算法就是 TarjanTarjan 的那套 dfsdfs 树+时间戳的搞法。 先求出所有桥,原图中的桥删去后的子图,每一个联通块都是一个双连通分量。 下面是求

2017-10-26 11:42:31 397

原创 [分块 DP] 51Nod1259 整数划分 V2

就是那个分块的套路。小于等于 n−−√\sqrt n 直接暴力背包。大于 n−−√\sqrt n 可以发现物品最多取 n−−√\sqrt n 个,所以就用旋转体积背包那样搞。 总复杂度 O(nn−−√)O(n\sqrt n)#include<cstdio>#include<algorithm>using namespace std;typedef long long LL;const in

2017-10-26 07:45:38 487

原创 [补集转化 DP] ZROI 2017提高7 强军战歌

这题当时打的比较复杂的 DPDP,需要写 nn 棵有标记的线段树,复杂度是对的,但常数贼大…被卡成70… 实际上补集转化一下就变得很简单了。 先求出所有满足删完之后是个不降序列,但没有考虑之前是否已经不降的方案数。然后扣去不合法的。 我们可以 DPDP 求出 resires_i 表示长度为 ii 的不降子序列个数。就可以直接求答案了: ∑i=1nresi∗(n−i)!−∑i=2nresi∗i

2017-10-25 21:17:03 482

原创 [DP] Codeforces #626F. Group Projects

显然是 DPDP。这种贡献和最值有关的,一般用按顺序插入的方法 DPDP,会简单很多。有挺多类似的题的。 这题就是 fi,j,kf_{i,j,k} 表示插入了前 ii 个,有 jj 个块开发待插入,总代价为 kk。 每次插入 i+1i+1 就考虑是新开一个块还是插入原有块中,是否要闭合块。转移 O(1)O(1)。 有个问题就是一个块的贡献是延迟计算的,即闭合后才会确定贡献。kk 应该记什么呢?

2017-10-25 19:45:32 419

原创 【施工中】【持续更新】部分刷题记录

部分刷题记录

2017-10-25 18:40:28 466

原创 [DP] Codeforces #623B. Array GCD

这题要找到一个突破点,不然难以下手。 注意到题面说不能全部删完,所以 a1,ana_1,a_n 至少有一个是不删去的。 这样就简单了,我们暴力得到 a1,a1+1,a1−1,an,an+1,an−1a_1,a_1+1,a_1-1,a_n,a_n+1,a_n-1 的质因数。共O(logV)O(\log V) 个。 然后枚举质因数,就可以 DPDP 了。fi,0/1/2f_{i,0/1/2} 表示

2017-10-25 18:02:54 436

原创 [贪心 + DP] Codeforces #571B. Minimization

不错的题。 容易想到按模 KK 分类 。每类的贡献时独立的,就是∑i|xi−xi+1|\sum_{i} |x_i-x_{i+1}| 这样的形式。如果我们已经确定了每类是哪些数,那么同类中排个序是最优的。 如何分配数分在哪一类呢 ? 发现我们一定是把连续的数放在一起比较优。 这样贪心的分析一下就变的很简单了,直接把 aa 数组排序。然后就是要把a分成 KK 段,每段的代价是末尾的值减去开头的值。

2017-10-25 14:46:20 272

原创 [构造 分块] Codeforces #576C. Points on Plane

实际上就是个莫队的思想啊….. 哈夫曼距离就可以看作莫队时移动代价,然后就那样分块地排个序就好了。 过不了就稍微调一调块大小多试几次…#include<cstdio>#include<algorithm>using namespace std;const int maxn=1000005;int n,m,blk,_max;struct data{ int x,y,id;

2017-10-25 13:04:21 367

原创 [杂题] Codeforces #577B. Modulo Sum

简单题。 a1,a1+a2,a1+a2+a3,a1+a2+a3+a4...a_1,\quad a_1+a_2,\quad a_1+a_2+a_3,\quad a_1+a_2+a_3+a_4... 抽屉原理,这些数模m一定会有相等的或为 00 的。容易想到,当 n≥mn \ge m 时是一定有解的。 所以直接 O(m2)O(m^2) 搞搞就好了。#include<cstdio>#include

2017-10-25 11:51:22 381

原创 [组合] Codeforces #571A. Lengthening Sticks

一开始正着做很复杂,然后发现补集转化一下就很方便了,随便搞一下…#include<cstdio>#include<algorithm>using namespace std;const int maxn=100005;typedef long long LL;int a,b,c,L,d;LL ans;LL get(int a,int b,int c){ int x=min(L+

2017-10-24 20:54:28 437

原创 [Lucas + 高维前缀和] HHHOJ#75. 虚妄之诺

我太菜了…做过类似的题还不会做…. 这题和之前做过的 ZROI 2017提高2 World Of Our Own 很像。总体思路就是异或的贡献是一个组合数的式子,用卢卡斯判断组合数奇偶,就转化成了子集和的形式,经典的高维前缀和就好了。 具体来说,我们考虑每个点对根的贡献,只需关注它到根的路径上的点被加的贡献。 1 1 1 1 1 1 1 1 1 1 1 2 3 4

2017-10-24 15:10:02 717

原创 [枚举 线段树] 51Nod1494 选举拉票

直接做不太可做,我们可以枚举一个 dd 表示其他人最大值不大于 dd 时的方案数。 这样就好做多了,比 dd 大的部分就一定要全部扣掉。然后如果自己的票数不足 dd ,就需要在剩下的所有票里取最便宜的前几个,需要线段树询问前k小值的加和。#include<cstdio>#include<vector>#include<algorithm>#define Fir first#define Se

2017-10-24 07:54:53 453

原创 [杂题 单调性] Codeforces #121D. Lucky Segments

算是蛮好的题。 首先 Lucky numberLucky\ number 可以全部预处理出来,大概 10510^5 的规模。 答案取的数字一定是个连续的区间,考虑我们其枚举右端点,左端点是有决策单调性的。就想到可以 22-pointerpointer 搞一下。 剩下的问题就是如何快速判断一个区间是否合法了。 显然对于一个区间,肯定只进行左移或右移。所以可以分开算。设 LiL_i 表示左端点小

2017-10-23 19:56:09 294

原创 [杂题] Codeforces #121C. Lucky Permutation

这题很 cfcf 。虽然 nn 很大,但由于 KK 只有 1e91e9,所以数列前面大部分数字是在原位的。13!=622702080013!=6227020800,只有后面不到 1414 位会变化,后面暴力就好了。 前面的 11到 n−13n-13,数位 DPDP 求答案。#include<cstdio>#include<algorithm>using namespace std;const

2017-10-23 17:00:20 390

原创 [二分+曼哈顿距离] 51Nod1671 货物运输

就是先二分答案,然后考虑如何验证。 满足 bi−ai≤midb_i-a_i \le mid 的点就不用管了,设传送点建在X,YX,Y, 则剩下的点需要满足: |X−ai|+|Y−bi|≤mid|X-a_i|+|Y-b_i|\le mid 这是如果我们发现考虑枚举一个端点什么的,很难搞。可以转化一下,注意上面的约束是一个曼哈顿距离的形式,也就是说把 (X,Y)(X,Y),(ai,aj)(a_i,

2017-10-23 07:55:22 365

原创 [杂题 思维] 51nod1448 二染色问题

好题,思路很巧妙。想到逆着搞就简单了。 考虑最后覆盖的一次,一定形成一个 K∗KK*K 的同色子矩阵,我们把它拿掉,则这些位置的露出的颜色是任意的。我们不断重复找可能的同色子矩阵,一层层剥掉。 最后判断是否存在一定是黑色的点即可。#include<cstdio>#include<algorithm>using namespace std;const int maxn=35;int _te

2017-10-21 22:42:39 375

原创 [杂题 暴力 ST表] 51Nod1487 占领资源

这种题看似很暴力,但也不能太暴力,需要一定的思考。 我们先枚举一个塔,再考虑下一个塔,注意到第2个塔与第一个塔有重叠的只有最多 K2K^2 个,即暴力枚举交在哪里,直接就得到了。 对于这些有重叠的暴力算答案,剩下的都和第一个塔没有重叠,就挑一个最大值即可。 除去 K2K^2 个元素的最大值,不要用什么线段树单点修改,直接 STST 表预处理,跳过 除掉的元素,一段一段询问最大值即可。#incl

2017-10-21 21:43:08 313

原创 [DP] 51Nod1048 整数分解为2的幂 V2

这题是 51Nod1383 的升级版。nn 是103010^{30} 做法是神奇的 DPDP。在而二进制下考虑。 设 fi,jf_{i,j} 表示,组成2i2^i,用的最大数是 2j2^j 时的方案数。 转移就是 fi,j=fi−1,k+fi−1−k,j−kf_{i,j}=f_{i-1,k}+f_{i-1-k,j-k} 然后就是类似的每位合并。gi,jg_{i,j} 表示组成 nn 二进制下

2017-10-21 15:25:43 334

原创 [递推] 51Nod1383 整数分解为2的幂

简单的递推,类似背包那种加 11 或翻倍的思路。 写这题其实只是水一篇 blogblog ,其实注意还是要做 51nod1048 加强版……#include<cstdio>#include<algorithm>using namespace std;const int maxn=10000005,MOD=1e9+7;int n,f[maxn];int main(){ scanf(

2017-10-21 08:53:18 335

原创 [组合 卡特兰数] 51Nod1556 计算

卡特兰数的简单应用。就是枚举加几个0,剩下的就是卡特兰数相关的理论。 设加 nn 个 11,mm 个 −1-1,则满足前缀和非负的方案数为 (n+mm)−(n+mm−1){n+m \choose m}-{n+m\choose m-1}。 由于这题最后的总和没有规定,所以我们需要算 f(x)f(x) 表示 n+m=xn+m=x 时的所有方案: f(x)=∑m=0⌊x2⌋( (xm)−(xm−1)

2017-10-21 08:32:23 356

原创 [杂题] Codeforces #484B. Maximum Value

这种 cfcf 的小题很 zicizici 啊。题不难但是感觉很好。 ai mod aj=d, aj∗k=ai−da_i \text{ mod } a_j=d,\ a_j*k=a_i-d 值域不大,就直接在值域上做。可以想到,先枚举 aja_j 再枚举 kk,预处理 nxtinxt_i 表示 从 ii 开始向左找第一个出现的数字。就好了。 O(nlogn)O(n \log n) 。注意范围要开

2017-10-21 07:05:59 315

原创 [扫描线 + 线段树] 51Nod1672 区间交

这题数列都是非负的,所以就比较简单了。 可以扫描线,枚举左端点,然后考虑覆盖了左端点的区间,挑右端点第 KK 大就好了。#include<cstdio>#include<vector>#include<algorithm>#include<cstring>#define Fir first#define Sec second#define mp(x,y) make_pair(x,y)

2017-10-20 20:46:22 294

原创 [构造] 51Nod1385 凑数字

首先考虑 n=9999...999n=9999...999 这种情况,没法怎么节省,每位都有 1010 种可能,只能 98765432109876543210 重复位数次,总长度为 10∗len10*len 。 所以对于一个一般的长度为 lenlen 的 nn,至少需要10∗(len−1)10*(len-1)。 现在考虑最高位取非 00 的情况。注意到当最高位小于 nn 的最高位时,都需要加一个

2017-10-20 19:34:34 359

原创 [贪心] 51Nod1476 括号序列的最小代价

要看清问题的本质。 实际上就是每个位置有两个权值,规定有多少个取的是第1个权值,剩下取第2个权值,求权值和最小值。 还需要满足括号序列合法,即把(看作 11,) 看作 −1-1,所有前缀和都非负。 假如不管括号序列,就直接先把所有的都取第一种权值,然后按差值排序,贪心的取。 而括号序列只是限制了序列的每个前缀至少需要几个是(。 依然贪心就好了。先把待定的位置都设为)。从左到右扫,若当前前缀

2017-10-20 18:30:54 455

原创 [贪心] 51Nod1288 汽油补给

经典题吧…考虑最近的一个比当前位置便宜的,若能到达,就原地加油至刚好能到那个位置,然后过去。若加满油都到不了,就先原地加满油,在能到达的位置中选最便宜的去。 数据结构优化一下。#include<cstdio>#include<cmath>#include<algorithm>using namespace std;typedef long long LL;const int maxn=1

2017-10-20 15:12:16 521

原创 [SET维护DP] Codeforces #875E. Delivery Club

好题。首先不难想到二分答案。验证就是写出状态 n2n^2 的 DPDP,类似 二取一维数组 的搞法: fi,jf_{i,j} 表示前 ii 个点已走过,两个人分别在 ii 和 j, (i>j)j,\ (i>j) 。 fi,j→fi+1,j(ai+1−aj≤mid),fi,j→fi+1,i(ai+1−ai≤mid)f_{i,j} \rightarrow f_{i+1,j}(a_{i+1}-a_{j

2017-10-20 12:13:09 329

原创 [二分图匹配] HHHOJ#51. Book

我太菜了……#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=10005,maxe=20005;int n,m,fir[maxn],nxt[maxe],son[maxe],tot;void add(int x,int y){ son[++tot]=y; nx

2017-10-20 08:49:43 694

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除