![](https://img-blog.csdnimg.cn/20201014180756919.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
hdu
lzh823046544
233
展开
-
Longest Common Substring
HDU 1403 经典的后缀数组题目,把两个字符串合并,维护一下后缀数组就好了 #include <bits/stdc++.h>using namespace std;const int maxn = 200010;char ch[maxn], All[maxn];int SA[maxn], Rank[maxn], Height[maxn], tax[maxn], tp[maxn]原创 2017-09-08 15:02:51 · 395 阅读 · 0 评论 -
The Closest M Points
题意:给定二维平面的一些点,然后q个询问,每个询问给定一个点,求距离这个点前num近的点 解法:裸的KD树,直接套模板 #include <iostream>#include <algorithm>#include <stdio.h>#include <string.h>#include <queue>using namespace std; #define LL long l原创 2016-10-13 14:21:22 · 335 阅读 · 0 评论 -
Joint Stacks
我是用数组模拟链表,每一个记录对于当前链(A或B)的 last 和 next ,然后在记录全局的(A 和 B)的 last 和 next 。那么对于 insert 和 pop 就直接做, 对于 merge 的操作,再用一个数组,在A B merge 后的开头+1, 结尾-1,那么在这一段中每次pop之后的跳转就用全局的进行跳转就好了。 #include <stdio.h>#include <st原创 2016-09-26 14:39:13 · 355 阅读 · 0 评论 -
Elegant Construction
水题:考虑把a[i]从大到小排序,然后每个节点都从后往前连边,那么就保证了不会出现重复情况(即连了一个几点却没有与这个节点的儿子直接连边),所以每个节点就要从后往前连a[i]条边,如果没法连就是不合法的情况。 #include <stdio.h>#include <stdlib.h>#include <algorithm>using namespace std;const int maxn原创 2016-09-26 14:33:30 · 197 阅读 · 0 评论 -
Road
朴素线段树 分别用两颗线段树记录记录每一个道路第一次使用和最后一次使用的时间,然后通过类似前缀和的记录第i天的花费,时间复杂度为 NlogN #include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>using namespace std;const int maxn = 210000;int原创 2016-10-10 10:55:51 · 205 阅读 · 0 评论 -
Eighty seven
题意:给出n个数字,去掉其中不超过3个,问能否在剩下的数字中挑出10个使得和为87。 暴力+bitset优化 用 f[i][j][k] 表示去掉第 i , j , k 个能否满足,在剩下的数中用 bitset<88> s[i] 表示取 i 个数能构成什么数字,转移就好了。 #include <stdio.h>#include <iostream>#include <algori原创 2016-10-10 10:00:42 · 471 阅读 · 0 评论 -
List wants to travel
题解:树链剖分+区间合并。链剖注意一下因为是边权不是点权,所以我是忽略根节点,从第二的节点开始给dfs序,把对应节点的边权当作点权,之后的change和query都要注意一下。然后线段树记录三个值,l , r , val , 分别代表区间的左右值以及区间中一共有多少个不同的块,然后合并就比较显然了。注意的是当作区间查询的时候要注意以下细节。我是定义从s到t的路径,所以对于从s路径往上走的区间,我要合原创 2016-09-20 14:23:29 · 366 阅读 · 0 评论 -
Going Home
裸的最小费用最大流,原点到每一个H连一条费用为0,流量为1的边;汇点到每个m连一条费用为0,流量为1的边,H和m之间连一条费用为两点间曼哈顿距离,流量为1的边,跑一边最小费用最大流就是结果了 #include <iostream>#include <stdio.h>#include <stdlib.h>#include <algorithm>#include <string.h>#inc原创 2016-09-20 16:25:52 · 264 阅读 · 0 评论 -
odd-even number
数位dp,用 f[i][j][k][1/0]表示到第i位,数为j,奇偶连续了k位,1为满0为不满的方案数。然后f[i][j][k][] 就可以转移到下一位,假设为j1,如果 j1 与 j 同奇偶,那么直接转移到 f[i+1][j1][k][] 就好了,如果不同奇偶,那么就要判断一下 f[i][j][k][] 是否合法,及 j 和 k 不同奇偶性,就可以转移到 f[i+1][j1][1][],最后把所原创 2016-09-19 11:35:24 · 583 阅读 · 0 评论 -
Ants
题意:平面上有一些蚁巢,每只蚂蚁在任意蚁巢都会走距离自己最近的蚁巢,如果有多个那么就优先x最小,再到y最小。现在有多组询问,每组询问代表两只蚂蚁所在巢穴,问最终他们会不会相遇。 KD树+并查集 对于任意一个起点,到最后必定会在两个点之间徘徊,所以可以用并查集,KD树找出每个点最近的那个点就可以了。 #include <iostream>#include <algorithm>#incl原创 2016-10-13 14:32:19 · 394 阅读 · 0 评论 -
Lights
题意:给出n个点,定义两个点能相互到达当且仅当一个节点能够通过曼哈段距离到达另外一个节点,而且仅当遇到其他点才能拐弯。问图中是否所有节点都能相互到达。 线段树 题解:首先对所有点优先按 x 坐标进行排序,每次对于当前状态,我们都保证在搜到的 x 坐标左边的所有点满足两两之间相互连通,然后对于每一次新加进来的 x ,从下至上扫描每个点,并且找到对应 y 坐标最右边的点,那么该节点满足于左边节点满足连原创 2016-10-06 09:51:09 · 448 阅读 · 0 评论 -
Ugly Problem
要求把一个数分成不超过50个回文数的和。 其实每次都找一个尽量接近当前数值的回文数,可以证明数的数量大概会接近 log(数的长度)个。至于怎么找,我是先构造一个回文数,假设当前剩下的值为a,我把a的前一半翻折到后一半去,那么就得到一个回文数,但是这个回文数可能会比a要打,然后我从中间位置到到第一位进行查询,一但找到一个数大于0, 那么我就把这个数减一,并且把中间位置到这个数的所有数都赋值为9,原创 2016-10-08 14:34:00 · 690 阅读 · 0 评论 -
Instability
一个集合中如果包含三个点相互连通或相互都不连通,那么这个集合算是合法,问有多少个这样的集合。 我们反过来想,如果正着求有多少个这样的集合,那么重复状况很难排除,反过来算有多少种不合法的集合,发现其实种类只有很少,直接用全局减去这些不合法集合的方案数就是答案了。 ( 可以手动画一下,各种不合法的情况,而且由定理得到不合法情况点数不会达到6或以上) #include <stdio.h>#in原创 2016-10-08 14:24:47 · 186 阅读 · 0 评论 -
Triangle
水题:给出1~n长度的木棍,问最少取走多少根剩下的木条无法构成三角形。 剩下的木棍要最多的话就是斐波那契数列,而且n只有20,打表也可以。 #include <iostream>#include <stdio.h>const int f[21] = {0,0,0,0,1,1,2,3,3,4,5,6,7,7,8,9,10,11,12,13,14};int main() { int tt原创 2016-10-08 14:17:36 · 194 阅读 · 0 评论 -
Coconuts
给出n*m的图,图中有不超过200个障碍点,要求把所有连通块的大小从小到大输出。数据保证第一行和最后一行不同时存在障碍,第一列和最后一列不同时存在障碍。 我的做法就是大暴力+map记忆化。对于每一个障碍,找他周围是否存在好的点,如果存在就对这个点做bfs,因为200个障碍点配合边界最大包围的区域为1+2+…+199,所以如果超过这么多个点那么一定不是一个被包围的区间,还有一个优化就是如果行或列原创 2016-10-08 14:11:36 · 415 阅读 · 0 评论 -
Basic Data Structure
题意:给一个栈,有push , pop , reverse , query 。 query求从栈顶到栈底逐个求 NAND 的值, 如果栈为空就输出 Invalid. 解法:可以用双向队列来模拟操作,每次都记录最接近栈底的0的位置(两边都要),那么对于QUERY操作,如果存在0位置,如果在0之前有数字,那么到0这个位置就会变成1, 不然就是0。然后从0的位置往后一定都是1,对于每一个1,答案都原创 2016-10-08 13:59:06 · 484 阅读 · 0 评论 -
Minimum’s Revenge
水题:对于1~n,两点距离为两点的lcm值,求最小生成树。 考虑每个点都与1相连,就是 2+3+..+n。 #include <cstdio>long long n;int main() { int t, ca = 0; scanf("%d", &t); while (t--) { scanf("%lld", &n); long lon原创 2016-10-08 13:50:24 · 419 阅读 · 0 评论 -
Magic boy Bi Luo with his excited tree
题意:给出一棵树,给出每个节点的价值以及每条路径的花费,每个节点不论经过多少次只能取一次对应的价值,而每条路径每通过一次都要付出对应的代价。要求输出从每一个节点出发的最大获利。 树形dp。 思路挺显然的,但是关键是对细节的处理。先做一次dfs,预处理出每一个节点往下走不会来(v1)以及回来(v2)的最大收益。然后第二次dfs就是伴随记录每个节点往父亲走不会来(fa_v1)以及回来(fa_v2原创 2016-10-07 10:25:38 · 402 阅读 · 0 评论 -
The Battle of Guandu
题意:给定n个村庄,可以理解每个村庄有无限多人,曹操向每一个村庄要一个人到固定的战场需要花费cost[i]的代价,同时会有一个人加入袁绍(敌方)的某个固定的战场。现在每个战场有一个重要值(0,1,2),0代表无关紧要,1代表不能输,2代表一定要赢,问曹操赢的最小花费。 差分约束的思想 其实对于每一个村庄,话费代价使得一个人到自己 i 战场一个人到敌方 j 战场,相当于花费这个代价,从自己对应的 j原创 2016-10-07 10:06:50 · 349 阅读 · 0 评论 -
hannnnah_j’s Biological Test
解法:首先相邻学生要隔k个空位,所以每个人就相当于占据(k+1)个位子,那么剩余空位 e = n-m*(k+1),要把这些位置插入到m个缝隙中(因为是个环,插入第一个前面与最后一个后面是相同的,所以为m个),这样的方案数就是C(n+e−1,e)C(n+e-1, e),如果考虑学生排列,那么方案就是C(n+e−1,e)C(n+e-1, e)*(m-1)!*n,但是由于学生是没有编号的,所以还要除以 m原创 2016-09-19 11:06:13 · 564 阅读 · 0 评论 -
Barricade
这题是裸的最小割,先从1节点bfs,再从n节点bfs,就可以找出最短路的所有路径,然后直接套模板就好了。 #include <stdio.h>#include <stdlib.h>#include <iostream>#include <math.h>#include <string.h>const int maxlongint=1 << 31 -1;int n, m, tot, ans,原创 2016-09-19 10:50:51 · 208 阅读 · 0 评论 -
Sort
解法:首先很显然是二分k的值,但是如果直接用堆来操作,时间复杂度会达到 Nlog(N)log(N) 的级别,而题目恶心之处就在于它把那个两个log的卡了,会T。所以考虑用另一个容器:链表。即对于每次前k个最小值合起来后插入到链表之中,因为插入的位置只会一直往后,所以用一个指针就好了,于是这样时间复杂度就降到了 Nlog(N)了,这样就不会T,但是还有一个细节,就是每次都找前k小的,如果不能刚好完全原创 2016-09-19 10:47:34 · 271 阅读 · 0 评论 -
Two
Two . . 题意:给出a,b两个字符串,问他们不必连续的字串中有多少对相同。 . . 解法:dp。f[i]表示对于b串当前读到的数字匹配到a串的第i个位置一共有的次数。 . .#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>using namespace std;cons原创 2016-08-24 10:26:17 · 164 阅读 · 0 评论 -
An Easy Physics Problem
An Easy Physics Problem . . 题意:平面上一个点与圆,点延一个方向前进,问能否达到另外一个点。 . . 解法:分两种,1是相撞,2是相离或相切。对于第二种直接求解就好了,而第一种注意一下精度,考虑点出现在相撞前的地方等就好了。 . . 队友代码#include <cstdio>#include <iostream>#include <cmath>#i原创 2016-09-12 11:04:40 · 685 阅读 · 1 评论 -
Binary Tree
Binary Tree . . 题意:树上每个点都有个权值,根节点为1,对于权为x节点,左儿子为2*x,右儿子为2*x+1,问从根节点往下走k步,每一步怎么取(+ 或 -),使得最后达到m值(中间能出现负数)。 . . 解法:注意 N <= 2^K,所以一路向左,最后一个向右取恰好为2^K。那么对于N比较小的,我们考虑和N与2^K作差,如果为奇数,那么最后一个点向左取即可,这样保证了差一原创 2016-09-12 10:58:17 · 180 阅读 · 0 评论 -
Kingdom of Black and White
Kingdom of Black and White . . 给定一个01串,相邻相同的数字为一块,串的权值定义为所有块长度的平方和。求最多改变一个值使得权值最大。 . . 解法:首先对于一个连续串,不会改变中间的值,只会更改两头的值,所以先算好原来所有块的长度以及权值,然后一个个更改判断是否会变大就好了,注意一下只有长度为1的块就好了。 . .#include <iostream>原创 2016-09-12 10:43:43 · 282 阅读 · 0 评论 -
LCM Walk
LCM Walk . . 假设 x = p * k , y = q * k ( k = gcd(x,y) ) 那么 z = p*q*k. 下一步会跳到( k * p * (1+q) , q * k ) 或者 ( p * k , k * q * ( 1 + p ) ),然后发现他们的gcd值并没有改变,所以推出无论跳多少步,gcd值永远不会改变。所以除去gcd的值后,每次都是 较大原创 2016-09-12 10:36:33 · 307 阅读 · 0 评论 -
Counting Intersections
Counting Intersections . . 题意:给出平行于坐标轴的线段,保证无重叠,端点相同的情况,问有多少交点。 . . 解法:首先我把数离散化,那么数的大小不超过4*10^5,这样就可以用树状数组。首先把平行于x、y轴的分开存。对于垂直于x轴的按x坐标排序,对于垂直于y轴的按x坐标左端点进行排序。然后扫描垂直x坐标轴的线段,可以很快找到所以垂直y轴的而且左端点在该x坐标左原创 2016-08-29 10:21:31 · 368 阅读 · 0 评论 -
Median
Median . . 题目挺水的。注意给定的序列是有序的,所以其实只有两种情况,要么给定的两段序列无关,要么出现重叠,这两个情况分开弄一下就好了。 . .#include <stdio.h>#include <stdlib.h>#include <string.h>#include <algorithm>using namespace std;const int maxn = 10原创 2016-08-29 10:11:42 · 395 阅读 · 0 评论 -
A Boring Question
A Boring Question . . 这题可以找规律(也可以证明这个规律),即m^0+m^1+…+m^n。用等差数列公式就可以求了,由于涉及除法,所以要用逆元。 . .#include <cstdio>const long long mo = 1000000007;long long m, n;long long mypow(long long x, long long n原创 2016-08-24 10:35:34 · 364 阅读 · 0 评论 -
World is Exploding
World is Exploding . . 解法:先求出所有Aa#include <iostream>#include <stdio.h>#include <stdlib.h>#include <math.h>#include <algorithm>#include <string.h>using namespace std;struct Node{ int id, va原创 2016-08-24 10:30:47 · 211 阅读 · 0 评论 -
A Simple Nim
A Simple Nim . . 这题写一个暴力看看每个数的sg函数的值,可以发现规律。 . .#include <cstdio>int x, y;int main(){ int t, n; scanf("%d", &t); while (t--) { scanf("%d", &n); x = 0; f原创 2016-08-24 10:37:46 · 265 阅读 · 0 评论 -
Cure
解法:其实发现读入超过一个很大的数之后小数点后5位不会发生改变的了,然后预处理前面的就好了。 #include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>using namespace std;const long long maxn = 1000000;double ans = 0;double原创 2016-09-19 10:27:17 · 351 阅读 · 0 评论 -
A Sweet Journey
A Sweet Journey . . 题意:一个人骑车,对于泥泞的路每单位耗费A点体力,对于平滑的路每单位恢复B点体力,问一开始最少储备多少体力能通过。 . . 解法:直接从0开始求,记录体力的最小值。如果小于0那么就储备那么多就好了,否则就是0。 . .#include <iostream>#include <stdio.h>#include <stdlib.h>using原创 2016-09-03 10:53:03 · 221 阅读 · 0 评论 -
Antonidas
Antonidas . . 题意:给出一棵树,每个节点为一个字符,问能否从一个节点走到另一个节点(路径不重复),使得得出给定的字符串。 . . 解法:dfs+剪枝。假设把1当作根节点,然后dfs一次记录每个节点往下最多能走多远。然后直接暴力dfs扫描能否有满足的路径,如果对于当前点要往下走就判断最远是否有可能完全匹配上,加上这个剪枝就可以过了。 . .#include <iostre原创 2016-09-03 10:44:13 · 336 阅读 · 0 评论 -
Puzzled Elena
Puzzled Elena . . 题意:给定一棵树,1为根节点,问每个节点的子树有多少个与他互质的数。 . . 解法:DFS序加容斥原理(莫比乌斯),DFS时用一个全局数组记录,count[i] 表示到当前结点能被i整除的有多少个数,由于可以保证每个数的因数不会超过6个,所以是n*2^6的,然后就是容斥原理了,对于奇偶的不同组合进行不同的操作,第一次遍历到当前结点把容斥的值减掉,然后原创 2016-09-03 10:36:41 · 330 阅读 · 0 评论 -
physics
physics . . 首先相同质量完全弹性碰撞即速度交换,那么其实这道题就相当于没有碰撞。而且由于C是相同的,所以如果一个速度开始是在第k位,那么经过t时间这个速度还是第k位。于是排序之后题目就变成已知一个速度,问t时间后他会变为多少。f(t)实际上就是一个积分。 f[t]=C∗∫1f[t]+V0f[t] = C*\int\frac{1}{f[t]}+V0 然后V0放到左边,两边同时对t原创 2016-08-24 11:16:14 · 303 阅读 · 0 评论 -
Rikka with Parenthesis II
Rikka with Parenthesis II . . 题意:给定一个由“(”,“)”组成的序列,看交换其中两个位置的符号使得序列合法(一定要交换)。 . . 解法:弄一个队列如果出现相邻的()就出队,然后记录有多少种不合法的情况,比如队列开头为),那么就把这个替换成(,并记录有一个不合法,如果最终队列不为空且最后为(,那么替换成)并记录。最后如果恰好只有两个或没有不合法那么就可以了原创 2016-08-24 10:58:53 · 189 阅读 · 0 评论 -
Ball
Ball . . 解法:贪心。因为相同的数字相互之间位置不交换更优,对于序列a的第一个1就期望移到序列b的第一个1的位置,一次类推。那么先把b的序列固定顺序,然后在赋给a序列每个数期望的位置。然后对于每次给的l,r就把l~r排一次序,看最后是不是1~n就行了。 . .#include <cstdio>#include <algorithm>using namespace std;原创 2016-08-24 10:53:05 · 229 阅读 · 0 评论 -
Windows 10
Windows 10 . . 解法:首先可以保证每次相同长度的操作不会超过一次,因为如果选择两次那么选择当前长度+1的操作会更优,然后每次都贪心搜索。先预处理出每种长度的操作所下降的值,然后每次都贪心找到尽量接近的数来操作,然后每次都判一下选择比当前数大于等于的操作是否更优,记录操作的步数以及更换的次数。注意音量小于0的情况是直接变为0的。 . .#include <iostream>#原创 2016-08-24 10:43:54 · 361 阅读 · 0 评论