- 博客(121)
- 收藏
- 关注
原创 noip2012 图论+贪心+二分
首先,这道题是有二分性质的,就是说时间放的越长,能切断的点就越多。然后就是贪心验证。 刚开始这样想的——对于每一次验证,按军队深度(与根之间的距离)从排序后, 1.一个点在给定时间内跑不到第二层,就尽量往上跑。 2.如果跑到第二层,就填上这一层。 3.如果跑到第二层,发现这点填过了,就跑到根,记录一下剩余时间。 这样之后bfs,没有填过的第2层由跑到根的点补一下。 调了一天,发现思路错了
2020-03-26 21:48:38
587
原创 bzoj 1031 字符加密 后缀数组
把整个前n-1个字符复制到字符串末尾,求个后缀数组搞就可以。#include<cstdio>#include<cstring>#include<iostream>#define maxn 200010using namespace std;char s[maxn];struct Suffix{ int sa[maxn],rank[maxn],height[maxn];
2017-04-25 16:19:13
574
2
原创 bzoj 3944 Sum 杜教筛
我不太会用数学公式,但还是尽量写一写。其中sigma为求和,除法默认下取整。 令g(n)=sigma( d|n ) f(d); 令F(n)为f(n)的前缀和,G(n)为 g(n)的前缀和,要求F(n)。 G(n)=sigma(i=1~n) sigma( j|i ) f(j) ; G(n)=sigma(j=1~n) n/j * f(j) ; G(n)=sigma(j=1~n) F(n/j)
2017-04-25 16:14:27
570
原创 bzoj 4600 硬币游戏 博弈论
反硬币操作与c无关,只与2和3的指数有关。设sg[i][j]为2和3的指数分别为i和j时,且前面的硬币都不可翻时的sg值。然后就可以枚举p,q,对于每一个p,q,它的sg值为 sg[i-k*q][j]的异或和以及sg[i][j-k*q]的异或和,求mex。#include<cstdio>#include<cstring>#include<iostream>#define maxn 30005
2017-04-25 15:54:29
781
原创 bzoj 1982 Moving Pebbles 博弈论
这道题不好想,可以先想先手必败的情况,一个比较显然的情况是石子个数成对出现时先手必败,因为先手怎样做后手可以完全模仿去做。然后还有没有其他情况呢,没有。其他情况把成对的抵消掉之后,我们可以将最大的补到其他的上面,还是可以凑成上述情况。#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using name
2017-04-25 15:47:15
476
原创 bzoj 1188 分裂游戏 博弈论
同一堆里的每个豆子是相互独立的,sg[i]表示第i堆里一个豆子的sg值。 sg[i]=mex( sg[j]^sg[k] ) ;#include<cstdio>#include<cstring>#include<iostream>using namespace std;int n;int p[30],sg[30];int use[1000];int main(){ int T
2017-04-25 15:37:12
446
原创 bzoj 1299 巧克力棒 博弈论
不考虑从盒子中拿出这一操作,则剩下的部分就是一个Nim游戏。所以先手第一次只要拿到异或和为零的巧克力棒就必胜。因为若对手选择吃巧克力棒,则是必败局面。若选择拿出巧克力,则新的异或和一定不为零,因为如果一组巧克力异或和为零,则先手可以第一次的时候拿出来。 直接dfs就可以。#include<cstdio>#include<iostream>using namespace std;int n;
2017-04-25 15:30:54
694
原创 bzoj 2179 FFT快速傅里叶
真 · 背板子。好像是用到了分治思想。#include<cmath>#include<cstdio>#include<cstring>#include<complex>#include<iostream>using namespace std;double pi=acos(-1);typedef complex<double> E;E a[140005],b[140005];voi
2017-04-25 12:31:33
476
原创 bzoj 1874 取石子游戏 博弈论
博弈论基础题,第一次写博弈论题目。 每堆石子的游戏是相互独立的,一个局面是由这n堆石子n个子游戏构成。 对于每堆石子,用sg[i]表示有i个石子的sg值,sg值由它的后继状态推过来:sg[i]=mex(sg[i-b[j]]); 最后的答案即为 : sg[ a[i] ] 的异或和;若ans=0则先手必败,否则先手必胜。 做第二问时,则按照输出的顺序枚举,第i堆移走k个的答案为ans^sg[a
2017-04-24 22:06:55
663
原创 bzoj 3295 动态逆序对 CDQ分治
每删除一个数对答案的影响是 前面比他大的数的个数+后面比他小的数的个数。问题变成了插入一个数并求出前面有多少数比他大(后面小的数可以用同样方法求)。 首先这可以用一个二维数据结构做。 CDQ分治的强大之处在于它能够压掉一维。它的主要思想是把操作分为两部分,计算前半部分修改对后半部分询问影响,然后递归处理两部分。 我这个代码写的太丑了,调了一天,,,还不如去写树套树>_<。#include<cs
2017-04-21 11:53:58
422
原创 bzoj 4698 Sandy的卡片 后缀数组
可以把原序列转化为差分序列,题意就变成了求这n个差分序列的最长公共子串。然后就可以连成一串,用后缀数组做。二分一个答案,询问是否有连续n个后缀LCP>=mid而且首位所属的串不相同。#include<cstdio>#include<cstring>#include<iostream>#define maxn 1100005using namespace std;void read(int
2017-04-19 12:07:40
457
原创 bzoj 2693 jzptab 莫比乌斯反演
首先,积性函数的约数和也是积性函数。 然后,比较尴尬的是我不太会用数学公式。 所以,大家就不要浪费时间看我写的博客。#include<cmath>#include<cstdio>#include<iostream>#define LL long long#define maxn 10000005using namespace std;LL mod=100000009;LL sum(
2017-04-17 12:43:16
429
原创 bzoj 2440 完全平方数 莫比乌斯函数
二分答案,求1~n里有多少个非完全平方数。 ans=n - (n/2^2) - (n/3^2) - (n/5^2) - (n/7^2)…… 然后再加上出现两次的,减去出现三次的…… 这是莫比乌斯函数。#include<cmath>#include<cstdio>#include<iostream>#define maxn 60005#define LL long longusi
2017-04-17 12:36:45
449
原创 bzoj 3940 & 3942 KMP || AC自动机
3942题解: 定义f[i] 为S串以第i位结尾的后缀,最长可以是T串多长的前缀,这一个可以用KMP匹配。 可以用一个first数组记录i字符前一个未被匹配的位置是哪一个,当f[i]=len(T)时,就可以将最末尾的len(T)个字符匹配了。 3940只需要把KMP换为AC自动机就可以。3942:#include<cstdio>#include<cstring>#include<iostr
2017-04-15 07:15:27
453
原创 bzoj 2553 禁忌 AC自动机+期望DP
先考虑一个串A如何划分价值最大,只需要按照所有T串在A中匹配的右端点排个序贪心去选,也就是希望我在A中匹配i个禁忌串,最靠后的右端点应该尽量靠前。 在AC自动机上对应为:只要走到一个禁忌串的终止节点,就将它划分出一段,(这里的终止节点包括那些顺着fail指针能走到终止节点的点)。 可以设dp[ i ][ j ]为在AC自动机上走了i步,走到了j节点的概率。 dp[ i ] [ ch[j][k]
2017-04-15 06:57:08
591
原创 bzoj 1212 L语言 Trie+DP
f[ i ] 为串前i位能否被理解,单词长不超过10,所以f[ i ]可以暴力转移……#include<cstdio>#include<cstring>#include<iostream>#define maxn 205using namespace std;char s[1500005];struct Trie{ int val[maxn]; int ch[maxn]
2017-04-15 06:36:23
500
原创 bzoj 2938 病毒 AC自动机
在补全之后的AC自动机上顺着child找环而不经过终止节点,如果存在环,则说明我们可以顺着这条路径构造无限长的字符串。#include<queue>#include<cstdio>#include<cstring>#include<iostream>#define maxn 100005using namespace std;char s[maxn];struct Trie{
2017-04-13 18:42:01
593
原创 bzoj 1030 文本生成器 AC自动机+DP
答案=方案总数-不合法总数; 设AC自动机上非法节点为终止节点(或fail指针指向终止节点的点) dp[ i ] [ j ]为当前在AC自动机上跑了 i 步 ,跑到 j 节点的方案数,其中过程不经过非法节点。 不合法方案数=sigma(dp[ m ] [ i ])其中 i 不是为合法节点。#include<queue>#include<cstdio>#include<cstring>#i
2017-04-13 18:36:04
355
原创 bzoj 2434 阿狸的打字机 AC自动机+fail树
询问x串在y串中出现次数,就是有多少y串的节点能顺着fail边跑到x的终止节点。所以建出fail树,求end[x] 为根的子树中有多少y的节点。 这个可以离线询问,用树状数组维护。#include<queue>#include<vector>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#de
2017-04-13 17:31:46
385
原创 bzoj 4402 Claris的剑 组合数学
#include<cstdio>#include<iostream>#define LL long long #define maxn 4000005using namespace std;int N=4000000;LL mod=1e9+7;LL fac[maxn],inv[maxn];LL pow(LL x,int y){ if(y==0) return 1;
2017-04-01 15:05:29
489
原创 Codeforces 785 D 组合数阶乘逆元
我不会写公式……….#include<cstdio>#include<cstring>#include<iostream>#define maxn 200020#define LL long longusing namespace std;char s[maxn];LL inv[maxn],fac[maxn];int N=200002;LL mod=1e9+7;LL pow(LL
2017-03-31 19:34:38
502
原创 bzoj 2502 清理雪道 上下界网络流最小流
首先可以用一种类似退流的思想,先建图跑可行流,然后删掉原图的汇点tt~源点ss之间的边,设这条边的流量为x1,再跑tt~ss的最大流x2。答案就是x1-x2。另一种做法,先不加tt~ss的边跑最大流,然后加边跑最大流x2,答案就为x2。#include<queue>#include<cstdio>#include<cstring>#include<iostream>#define maxn
2017-03-30 15:25:10
512
原创 bzoj 2055 80人环游地球 上下界费用流
这题像上下界网络流一样,把一条边拆成三条,其中原图中的边权值不变,连向超级源点和汇点的边权值改为0就可以。然后把边合并一下。答案为每条边最小容量*权值+建完图后最小费用流。#include<queue>#include<cstdio>#include<cstring>#include<iostream>#define maxn 405#define LL long longusing n
2017-03-30 14:20:28
430
原创 bzoj 1670 护城河的挖掘 凸包
#include<cmath>#include<cstdio>#include<iostream>#include<algorithm> #define maxn 5005using namespace std;struct point{ double x,y; point(){} point(double x1,double y1){x=x1,y=y1;}
2017-03-29 14:22:56
381
原创 bzoj4033 HAOI2015 T1 树形DP
dp[i][j]表示以i点为根的子树中选j个黑点,所能达到的最大价值。#include<cstdio>#include<cstring>#include<iostream>#define maxn 2005#define LL long longusing namespace std;struct E{ int to,nxt,d;}b[maxn<<1];int fst[max
2017-03-20 14:26:21
352
原创 bzoj 3238 ahoi2013差异 后缀数组
#include<set>#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define maxn 500005#define LL long longusing namespace std;char s[maxn];set<int> S;set<int>
2017-03-17 23:18:32
321
原创 bzoj 3110 K大数查询 整体二分
#include<cstdio>#include<iostream>#define maxn 50005#define LL long longusing namespace std;int n,m;struct Que{ int op,l,r,x,id; void read() { scanf("%d%d%d%d",&op,&l,&r,&x);
2017-01-03 19:15:47
454
原创 bzoj 3339 Rmq problem 离线+线段树
首先可以在O(n)的时间内求出1~i(for i 1~n)的答案ans[ i ]。然后对于l~r的答案与l+1~r答案的关系,把i~nxt[ i ]-1的所有大于a[i]的ans都改为a[i]就可以了,nxt[ i ]表示下一个最近的 值也是a[i]的位置。询问排一下序。#include<cstdio>#include<iostream>#include<algorithm>#define m
2017-01-03 19:13:08
293
原创 bzoj 2141 排队 树套树
交换位置L,R,对答案产生的影响是L,R内(比L大的数个数-比L小的数个数)+(比R小的数个数-比R大的数的个数)+(L和R交换后应该+1或-1)。求这个东西用树套树就可以(做数据结构做傻了,还有很多其他优秀的做法)。#include<iostream>#include<cstdio>#include<algorithm>#define maxn 1700005using namespace
2017-01-03 18:57:12
410
原创 bzoj 3236 作业 莫队
题意:长度为n的序列,m次询问,每次给出l,r,a,b,求在[l ,r]区间内权值在[a ,b]区间的元素个数以及去重后的个数。 第一眼,这不是线段树套Splay裸题吗,码了半天,不对啊,去重没法做。想了想,权值套区间线段树可做,又码了半天,第二步还是不会做。忽然发现可以莫队,96s在bzoj卡过了。这道题树套树是可以做,正解好像是再分块优化莫队,使得端点移动变成O(1)。(专治数据结构学傻!)#
2017-01-02 16:08:42
377
原创 bzoj 3100 K大数查询 树套树
外层权值线段树,对于每个权值线段树节点,建立区间线段树。但是内层这样普通建树会TLE&&MLE。仔细想会发现,区间线段树不用都建出来,用到哪个点就开哪一个点,每次操作最多经过logn个权值线段树节点,访问每个权值线段树节点时,最多修改logn个区间线段树节点,所以区间线段树总节点个数nlog²n。注意longlong。#include<iostream>#include<cstdio>#incl
2017-01-01 22:34:33
476
原创 hdu 4010 LCT
注意标记下放时,子节点不为零时再下放,不然统计的时候会出问题……#include<iostream>#include<cstdio>#include<cstring>#define maxn 300005using namespace std;int fa[maxn],ch[maxn][2];int val[maxn];int Max[maxn],add[maxn];struct l
2017-01-01 15:15:35
430
原创 hdu 2475 box LCT
题意是箱子套箱子,每次移动箱子x到箱子y里,或询问x最外层的箱子。 这一道题根是固定的,不能换根。#include<iostream>#include<cstdio>#include<cstring>#define maxn 50005using namespace std;int fa[maxn],ch[maxn][2];int f[maxn];bool isroot(int x)
2017-01-01 10:56:45
429
原创 hdu 1512 左偏树
题意大概是有n只猴子,m次矛盾,a和b产生矛盾时,如果他们不认识,就会找各自认识中最强壮的猴子打架,然后打架的猴子权值减半,这两拨猴子就互相认识了,成了一群猴子,每次求合成一群后的最大权值。#include<iostream>#include<cstdio>#define maxn 100001using namespace std;int f[maxn];int find(int x)
2016-12-31 19:55:35
481
原创 poj 2201 笛卡尔树
这个数据结构看上去非常巧妙,不过没有找到实用的例题。。。。#include<iostream>#include<cstdio>#include<algorithm>#define maxn 50005using namespace std;struct Pair{ int key,aux,id; int fa,ch[2]; void print() {pr
2016-12-31 19:33:41
498
原创 poj 3261 Milk Patterns 后缀数组+二分
题意是求可以重复的出现次数超过k次的子串,最长是多少。 样例输入 8 2 1 2 3 2 3 2 3 1 输出 4二分验证是否有连续的k-1个height大于所验证的答案。#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define SZ 20005using nam
2016-12-27 08:03:15
407
原创 tyvj1860 后缀数组 模板
注意常数优化(优化输出等)。#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int MAXN=2e5+10;int n,sa[MAXN],tmp[MAXN],rank[MAXN],sec[MAXN],cnt[MAXN],height[MA
2016-12-26 17:19:44
388
原创 noip2016 愤怒的小鸟 状压搜索
这道题稍微卡了一下精度,浮点数直接判相等是会挂掉的。然后就是搜索,选定当前未选的最小编号,枚举其他的点确定一条抛物线(如果可以),然后把在这条线上的点都选上。确定抛物线推一下就可以。#include<iostream>#include<cstdio>#include<queue>#include<cstdlib>#include<map>#define LL long longusing
2016-12-21 20:40:47
1066
原创 bzoj2599 Race 点分治
给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000树的点分治,用数组cnt[x]记录与根距离为x最小多少条边,然后每搜完一棵子树,再用这棵子树的信息来更新cnt,避免统计同一棵子树中的点对。#include<iostream>#include<cstdio>#include<algorithm>#define maxn 20
2016-12-21 20:28:52
479
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人