指针式线段树 bzoj 1798 学习了指针,重写bzoj 1798数组本质是指针,所以可以buid(tr,1,n)一个Tree *tr指针,tr[1]指的是这个指针指向的下一个位置,不是开数组的那个tr,所以都改成了root#include#include#include#include#define ll long long#define inf 1e9#define md#define N 100
c++ primer 学习笔记(一) 2.1 基本内置类型2.1.1算数类型short 16位 long 32位 long long 64位(c++11新定义)wchar_t 用于确保可以存放机器最大扩展字符集中任意一个字符char16_t char32_t 为Unicode服务除bool型和扩展的字符型以外,其他整形可以划分为带符号的和无符号的字符型被分为 char/signed char/unsigned
bzoj 2989&&4170: 数列 首先所谓的“可持久化” 就是加入一个新的元素把看成平面上的一个点,graze函数就是曼哈顿距离求点集中曼哈顿距离≤k的,自然要转换为切比雪夫距离的一个矩阵内点的个数然后CDQ分治或者强上数据结构注意矩阵y坐标取min要和1算,因为查询的时候是L-1,而树状数组不允许查询负数位置#include#include#include#include #define ll lon
4556: [Tjoi2016&Heoi2016]字符串 字符串题不会做先想能不能把字符串反过来把字符串反序,建立后缀自动机,利用线段树合并算出每个位置的right集二分答案,用树上倍增找到对应的节点,看是否有[a+mid-1,b]中的数在right集中#include#include#include#include #define ll long long#define inf 1e9#define eps 1e-10#define m
bzoj 3825: [Usaco2014 Dec]Marathon 查询的答案就是完整走过所有点的距离-少走一个点可以减少的距离的最大值。所以线段树维护区间和,还有如果不走每个点,可以少走多少路然后答案就是sum[l+1,r]-max[l+1,r-1]没写%lld wa了一发#include#include#include#include #define ll long long#define inf 1e9#define eps 1e-1
bzoj 4282: 慎二的随机数列 结论:所有的未知数都可以出现在最优解中。所以,把每个确定的数减去它前面未知数的个数,计算lis就行膜拜了一下popoqqq大爷优美的lis#include#include#include#include #define ll long long#define inf 1000000007#define eps 1e-10#define mdusing namespace std
bzoj 4591: [Shoi2015]超能粒子炮·改 S(n,k)=S(n/p,k/p-1)*S(n%p,p-1)+C(n/p,k/p)*S(n%p,k%p)意思是根据lucas定理对于i/p忘记处理sum[0][?]了#include#include#include#include #define ll long long#define inf 1e9#define eps 1e-8#define md#define N 250
bzoj 4436: [Cerc2015]Kernel Knights T集表示已经确定不在S集内的点。对于一个点,如果不存在非T集的点挑战它,那么它一定在S集中。如果存在一个挑战它的点在S集中,那么它一定在T集中。用类似拓扑排序的方法,首先找出所有不被挑战的点,归入S,把这个点挑战的点y归入T集,然后y挑战的点的度数-1.最后剩下一些点在环中,满足每个点都被别人挑战,也挑战别人,因为是二分图,所以保证是偶环,所以把#include
bzoj 4530: [Bjoi2014]大融合 先说一下我的做法:没有强制在线,先建出来这棵树,然后发现x到它父亲的边的答案是 (目前连通块大小-x子树的大小)*(x子树的大小),这个子树大小也是指目前连通块内的子树大小,子树大小可以用线段树维护dfs序,进行线段树合并得到。子树size也可以用树链剖分做。#include#include#include#include #define ll long long#define inf
bzoj 4103: [Thu Summer Camp 2015]异或运算 水题,查询由ai^bj组成的矩形的子矩形内的k大值,行数和询问数都很少,所以可以枚举行数,跑可持久化字典树。注意不能 int l=0,r=2147483674,mid=(l+r)>>1,这个会爆int,开unsigned int 就行。还有,写可持久化主席树又忘了ch[i][0]=ch[pre][0], ch[i][1]=ch[pre][1]#include#include#i
bzoj 4104: [Thu Summer Camp 2015]解密运算 暴力做法: 已知长度为l的所有子串,可以推出长度为l+1的所有子串,比如样例已知长度为1的子串是?AAAABC,而以这些字符开头的字符串的结尾分别是AAAC?AB,而这些字符也是写在对应字符前面的字符,所以得到了子串{A?,AA,AA,CA,?A,AB,BC},然后再用相似的办法推出剩下的子串,但这样太慢了。我们只需要记录那个以?开头的字符串,每次这个字符串前面会加上一个新的字符,然后得知了这
bzoj 4592: [Shoi2015]脑洞治疗仪 线段树维护最长连续段的长度,然后暴力修改,暴力查询,这个复杂度应该是nlogn的。然而我调了好久。。。#include#include#include#include #define ll long long#define inf 1e9#define eps 1e-8#define md#define N 200010using namespace std;struct Tr { i
bzoj 4590: [Shoi2015]自动刷题机 刷题数是关于n单调递减的函数,所以可以二分答案判断。无解有两种情况,一种是无论n是多少都无法ac这么多题,一种是不存在n恰好ac这么多题,判断一下就好。#include#include#include#include #define ll long long#define inf 1e9#define eps 1e-8#define md#define N 100010using
bzoj 4597: [Shoi2016]随机序列 对于一个表达式序列 ****+??????? 一定有一个表达式序列 ****-??????? 与它相加为0,所以对答案有贡献的是第一个非*之前的序列乘上这个序列出现的次数。对于前i个数组成的序列,出现次数=2*3^(n-i-1),前n个数组成的序列出现次数为1.所以用线段树维护这个式子的值就好了,具体实现看代码#include#include#include#include #defi
bzoj 4571: [Scoi2016]美味 如果没有加法,这就是一道水水的可持久化trie,有了加法,我们就要用可持久化权值线段树,然后按位贪心,查询变成一个区间内是否存在数字。#include#include#include#include #define ll long long#define inf 1e9#define eps 1e-8#define md#define N 4000010using namespace
bzoj 3569: DZY Loves Chinese II 神题一道。将所有边分为树边和非树边,把所有非树边随机一个权值,然后树边的权值是所有覆盖它的非树边的权值的异或和。如果一个边集的存在一个非空子集的异或和为0,那么树是不连通的。原因是:(1)删除了一条树边和所有覆盖它的非树边,那么这些边的异或和为0(2)一个点的出边只有树边,且删除了所有与它相连的树边,因为这些树边的异或和一定存在一对相同的,所以也对。然后就是如何搞出树边的权
bzoj 2708: [Violet 1]木偶 最优策略一定可以把整个序列分成几段,每一段都是像这样子的红线表示不可匹配。所以可以排序后dp[i]表示前i个数最多删掉多少=max(f[j-1]+cal(j,i)) cal(j,i)表示j到i最多删掉多少个。注意是判断红线相连的两个是否能够匹配,而不是第i个和第i+k个能否匹配#include#include#include#include #define ll lon
bzoj 3702: 二叉树 发现子树中如何排列对于兄弟节点的逆序对是没有影响的,所以统计兄弟节点之间交换和不交换的逆序对数,取较小值即可。用线段树合并时直接计算逆序对的方式可以搞到nlogn。#include#include#include#include #define ll long long#define inf 1e9#define eps 1e-8#define md#define N 200010
bzoj 4000: [TJOI2015]棋盘 矩乘,题意坑爹,那个第一行是中间那一行,所以记录一行的状态就可以了。f[S]表示最后一行状态为S的方案数,然后暴力看能否转移。#include#include#include#include #define ll long long#define ui unsigned int #define inf 1e9#define eps 1e-8#define md#define N 70u
bzoj 4569: [Scoi2016]萌萌哒 一种会T的做法:发现并查集加边只会发生n-1次,所以只要一个较小的复杂度完成这n-1次加边即可启发式合并维护并查集,每次暴力修改所有属于小区间的fa值,用vector记录每个连通块内的数,暴力在线段树内修改hash值,复杂度logn,需要进行nlogn次线段树上hash把所有的fa hash起来,然后二分找位置,每次寻找log^2,需要进行On次#include#inclu
bzoj 4568: [Scoi2016]幸运数字 ST表维护线性基,用ST表维护不带修改的东西可以比树剖少一个log。注意维护线性基是60*60的复杂度。#include#include#include#include #define ll long long#define inf 1e9#define eps 1e-8#define md#define N 20010using namespace std;struct yts {
bzoj 4567: [Scoi2016]背单词 读题发现,只要保证每个字符串加入的时候它的后缀都加入了,那么总代价最大是n*(n-1)/2,所以不会出现第一种情况。建出一棵树,每个点的father是它最长的后缀,然后贪心每次走较小的子树就可以。找后缀可以字符串反序从短到长建trie注意在压字符串的时候,字符串大小要开总长度+字符串个数。#include#include#include#include#include#de
bzoj 1419: Red is good f[i][j]表示有i个R,j个B的期望,然后转移。注意输出多位小数下取整,小数点之后要06lldll ans=floor(f[now][B]*1000000);printf("%lld.%06lld",ans/1000000,ans%1000000);#include#include#include#include#include#define ll long
bzoj 4197: [Noi2015]寿司晚宴 看到题,就想到要利用质因子分解进行状压dp,但是质因子太多了,不能直接搞,于是考虑按最大质因子sqrt(n)分别讨论。对于最大质因子>sqrt(n)的每个数,只有一个质因子>sqrt(n),而<sqrt(n)的质因子是可以状压的。f[s1][s2]表示a选的集合恰好为s1,b选的集合恰好为s2的方案数,然后就想不到了。把所有数按照最大质因子分类,每一类分别转移。令dp[0/1][s1]
bzoj 3120: Line 这道题,摆着它40s的时限,隐藏着卡常数的真面目。180个点的矩乘,我默上了板子,却t成狗,加了一些常数优化才过。f[i][a][b][c][j]表示前i列,有a行结尾是011 b行结尾是01 c行结尾是0,出现j列全是男生的方案数转移 f[i][a][b][c][j]*C[c][e]*C[b][d]->f[i+1][d][e][f][j+(f==0)]常数优化:1.不要 ll *
CTSC&&APIO2016 旅游记&&被坑记 在帝都将近十天,回家之际,有一丝急迫,也有一丝眷恋。5.1 CTSC day0 坐前一天晚上的火车,很早就到达了北京,倒了3班地铁+一班公交到达了目的地,被yts大爷领着绕了一个大圈才到宾馆,累成狗。 宾馆很高级,房间里面有70元一瓶的水,冰箱里还有各种饮料(当然是喝不起的啦),床软的可怕。睡了1个小时,人还是虚的,背了一点板子。 中午被叫
bzoj 3176: [Coci 2012]Sort 由于第一次交换长度至少为2,所以进行完第一次交换之后,可以证明之后不再会出现长度为3的递减子段,那么就成了求逆序对、#include#include#include#include #define ll long long#define inf 1e9#define eps 1e-8#define md#define N 100010using namespace std;int c[
bzoj 4070: [Apio2015]雅加达的摩天楼 分层图最短路,令k=sqrt(n)如果p>k,那么从这个点出发只需要连如果p建有k+1层的分层图,把第0层视为每个位置的源点,对于p最后的建图:第1层到第k层每层都向对应的第0层连边权是0的边每一层相邻的%p相同的点互相连边权是1的边对于每个>k的,从出发点向可以到达的点连距离=跳跃步数的边发现这样内存不够,所以把k设小一点。写错的地方:1.少加了一种边
bzoj 4553: [Tjoi2016&Heoi2016]序列 令L[i]表示i可以取到的最小值,R[i]表示i可以取到的最大值。如果i可以成为子序列中j的前一项,必须满足 i<j a[i]<=L[j] R[i]<=a[j],然后cdq分治注意分治的写法,不然可能卡成暴力。比较好的办法是把a和L拆成两个东西。#include#include#include#include #define ll long long#define inf 1e
bzoj 4539: [Hnoi2016]树 开始读错题了,以后一定要好好读题!!!称原来给的大小为n的树为模板树,最后得到的树为答案树,把一次操作增加的节点看成一块,然后构成的树称为大树。答案树上两点的距离=两点分别走到所在块的根,在大树上走到两个块的lca,撤销进入块lca后两个点共同走过的路径。第一步的答案就是找到点到它所在块的根在原树中的距离第二步,把大树上两点之间的边权定义为答案树上这两个块的根的距离,然后倍增lca
bzoj 4547: Hdu5171 小奇的集合 读题,发现就是每次找两个最大的数,加入a+b,矩乘优化一下就好。然而,wa*inf,原因如下:1.读错题,答案求的是集合内所有数的和,我写成了所有加入的数的和2.忘记负数取模的问题3.不一定,A#include#include#include#include #define ll long long#define inf 1e9#define eps 1e-8#defi
bzoj 3609: [Heoi2014]人人尽说江南好 对于必胜方,游戏的最优策略是每次找最大的两个可以合并的数合并,但是如果出现(m-1) 2 1 1 ……的情况合并 m-1 和 2,这样无论必败方如何操作,这次游戏的总操作次数是一定的,因为这样的终局一定是一些m,然后一堆n%m,或者其他总操作次数和它相等的局面。这个终局的总操作次数相当于比没有m的限制少了这剩下的n/m上取整堆的合并次数,所以操作次数是(n-1)-(ceil(n/m)-1)
bzoj 3823: 定情信物 考虑每个n维超立方体的k维元素的“对角线”向量就是从n维中选出k维,每一维为+1或-1,答案就是C(n,k)*2^k,在预处理出逆元之后可以O(n)。但是由于p可以#include#include#define ll long long#define N 10000000using namespace std;ll rev[N];int p;void get_rev(int n){
bzoj 3755: Pty爬山 称关键点为使其改变目标的点,从一个点出发,到达的关键点是确定的,且如果一条路径上到达某个点为关键点,那么之后的路径和从这个点出发的路径相同,所以我们就要找出每个点出发走到的下一个关键点。首先找到每个点能看到的最高的山峰,维护每个点左面的上凸壳,右边的上凸壳,那么它能看到的最高的山峰就是这两个下凸壳的最后一个点中较高的点,而要寻找的关键点一定在这个点和那个较高的点之间。之后,把所有点按照到达
bzoj 4554: [Tjoi2016&Heoi2016]游戏 如果不考虑硬石头的限制,那么就是经典的二分图匹配,对于硬石头的限制,就把同一行/同一列再拆点。#include#include#include#include #define ll long long#define inf 1e9#define eps 1e-8#define md#define N 5010using namespace std;struct yts { int x,
4551: [Tjoi2016&Heoi2016]树 应该是和sdoi发生了同样的一道很好的想法题由于出题人没有想到某种做法变成了水题。这道题显然可以nlog^2n的树链剖分,但是有一种很好的并查集做法:用类似疯狂的馒头这道题的方法,维护father[i]表示离i最近的打了标记的祖先。把所有询问离线下来倒着枚举,如果某个操作是把点从标记变成不标记,那么把它的father变成它的父亲。#include#include#include
bzoj 1831: [AHOI2008]逆序对 可以证明在-1的位置填的数是单调不降的。看到数据范围n转移的时候,一个不是-1的位置贡献的逆序对数与它前面的-1的位置具体填了多少有关,所有考虑贡献提前计算,即如果这个位置是-1,把它前面和后面所有不是-1的位置形成的逆序对都计算进去,而不是-1的位置只需要把它和它后面不是-1的位置形成的逆序对计算进去(-1之间不会形成逆序对)。然后,树状数组优化求逆序对即可(但是数据范围好小,直接暴
bzoj 3430: [Usaco2014 Jan]Ski Course Rating 开始别人跟我说这道题时没告诉我对于所有点T的值都是一样的,也没告诉我是奶牛题,于是YY了一种二分答案+可持久化并查集的nlog^3n的做法:把所有边排序,建主席树维护加入的边权之后二分答案,在对应的权值的位置查询它所在的集合大小是否大于等于T然后又想了种nlog^2n的做法:并查集,对每个集合维护一个小根堆记录所有在这个集合内未达到T的点的T-size,然后启发式合
bzoj 2555: SubString 后缀自动机+lct维护fail树注意在copy q节点的信息的时候,right[cpy]=right[q],动态维护其他信息的时候也要注意这一点。#include#include#include#include #define ll long long#define inf 1e9#define eps 1e-8#define md#define N 1200010using na
bzoj 1790: [Ahoi2008]Rectangle 矩形藏宝地 我的这种做法MLE一个点,cheat过去了。把所有点按照x1排序,依次在线段树节点的x2位置加入区间[y1,y2]查询时,查询线段树区间[x2,n]是否存在一个区间包含[y1,y2],在它之前加入的点的x1查询是否存在一个区间包含这个区间:把这些区间去除被别的区间包含的区间,剩下的按照左端点排序,二分找到最大的y1显然,如果这个区间不包含查询的区间,那么其他区间也不可能,维
bzoj 2310: ParkII 带独立插头的插头dp,注意比环的插头dp的区别主要是在只有一个插头并且是独立插头的时候,有可能可以结束线路,剩下的就是2*2特判变成3*3特判。然后就是各种打错变量名,还有一个宝贵的经验就是手写二进制分解其实没有太麻烦。#include#include#include#include #define ll long long#define inf 1e9#define eps 1e
bzoj 4538: [Hnoi2016]网络 查询的是不包含x的链的权值最大值。树链剖分后,每条链变成O(logn)个区间,那么未被这个链包含的也有logn个区间,在这logn个区间上做修改即可。因为有删除操作,每个线段树节点开一个堆维护。#include#include#include#include#include#include#define ll long long#define inf 1e9#define ep
bzoj 4540: [Hnoi2016]序列 题意坑爹,不需要判断两个子串是否相等。然后这道题几乎就是bzoj 4262了。除了线段树做法,还可以用莫队用单调队列预处理出L[i]表示i左边第一个小于a[i]的位置,R[i]表示i右边第一个小于a[i]的位置。fl[i]表示以i为左端点的所有区间的答案,=a[i]*(R[i]-i)+fl[R[i]],因为[i,R[i])位置的贡献都是a[i],[R[i],n]这个区间的答案与fr
bzoj 4542: [Hnoi2016]大数 在p!=2且p!=5的情况下,x*10^k%p=0,则x%p=0,所以可以维护后缀和%p的值,然后用莫队求区间内相同的数的对数。p=2 or p=5 最后一位决定%p之后的值,yy一下即可#include#include#include#include#include#include#define ll long long#define inf 1e9#define eps 1e-8#
bzoj 2461: [BeiJing2011]符环 f[i][s1][s2][s3]枚举到前i个字符,前半段左括号-右括号的值是i,后半段未匹配的左括号个数是s2,未匹配的右括号个数是s3.后半段去掉已匹配的括号后一定是这样:)))(((。转移时依次枚举左边添加左括号,左边添加右括号。注意在右面添加右括号时,一种情况是减少一个未匹配的左括号,一种情况是增加一个未匹配的右括号。然后记忆化搜索。#include#include#
bzoj 4373: 算术天才⑨与等差数列 看到这个限制条件非常强,就不难考虑到hash。存在一个性质,只要知道这个区间的最大值,最小值,希望得到的等差序列就唯一确定,需要干的工作仅仅是看原来的序列和这个序列是否相同。首先,用各种特判:k=0很好做,若k!=01.相邻两项的差的gcd是k的倍数->维护差的gcd2.没有相同的项->维护pre的最大值3.区间和等于这个等差序列的和->维护区间sum用线段树维护一下就
bzoj 1913: [Apio2010]signaling 信号覆盖 每个凸四边形对答案的贡献是2,每个凹四边形对答案的贡献是1.凹四边形贡献1是显然的,凸四边形贡献是2的原因是:如果一个点在一个三角形的外接圆内,那么α+β现在考虑如何求凸四边形个数和凹四边形个数,凹四边形比较好求。枚举每个点,设其为p,统计有多少个三角形覆盖了这个点,那么,以这个点为中心的凹四边形就有多少个。考虑补集转化,求有多少三角形不覆盖这个点。将所有剩余点极角
bzoj 4262: Sum 把询问离线下来,查询max和查询min相似,现在只考虑查询max令sum[l,r,x]表示l到r内的数为左端点,x为右端点的区间询问的答案那么询问就是sun[l1,r1,r2]-sum[l1,r1,l1-1]从1到n枚举x,维护区间线段树表示sum[l,r,x],发现从x-1转移到x的过程中,每个数加上了max(a[pos]..a[x])的答案。用单调队列维护一个单调递减的序列,由
bzoj 3832: [Poi2014]Rally 首先建图,S向每个点连边,每个点向T连边,那么问题就变成了求S-T最长路-2拓扑图的每条边都是从拓扑序小的点连到拓扑序大的点经过某条边的最长路是从S沿最长路走到这条边的x,再从y沿最长路走到T所以,扫描整个序列,维护所有pos[e[i].x]维护所有的边,就是在扫描到x的时候,把所有到达x的边删除,查询,把所有从x出发的边加入。我一直在想把最长链拉出来,然后用类似上面的方法维护
bzoj 4537: [Hnoi2016]最小公倍数 一部血泪史:开始我想到分块,但是一直在想直接按照a的权值分块,却发现无论怎么做复杂度都不对。看题解,发现直接把边分块就行。题解:考虑暴力做法,就是把所有想到这个做法,不难想到分块,把边按照a为第一关键字,b为第二关键字排序,分成若干块。每次把前i块的边和第i块的询问按照b的大小排序,按照b的权值从小到大把边加入并查集,注意如果这条边的a权值>这一块的询问的最小a权值,那么不
bzoj 4446: [Scoi2015]小凸玩密室 #include#include#include#include #define ll long long#define inf 1e9#define eps 1e-8#define md#define N 200010using namespace std;ll f[N][20],g[N][20],A[N],B[N],dis[N];int fa[N],lson[N],rson[N],dep[N]
bzoj 3956: Count 发现好点对互不跨立,所以只有O(n)个,用单调队列找出这O(n)个然后用主席树维护就可以了。对于a[i]相等的情况的单调队列写错了一些细节。#include#include#include#include #define ll long long#define inf 1e9#define eps 1e-8#define md#define N 300010#define TR 1
bzoj 2809: [Apio2012]dispatching 线段树合并or可并堆or树上主席树我写的线段树合并,注意query递归到最后要return sum/x,就是只剩一个数,但是个数太多。#include#include#include#include #define ll long long#define inf 1e9#define eps 1e-8#define md#define N 100010#define TR 3200
bzoj 4524: [Cqoi2016]伪光滑数 看到求第k大,k很小,首先应该想到k路归并。利用可持久化可并堆进行dpg[i][j]表示前i个素数,用了j个质因子可以表示的数的集合g[i][j]=sigma(g[i-1][j-k]*p[i]^k) sigma表示集合的并,乘法用打标记实现。然后k路归并,按照使用了的质因子个数分类。令mx[j]表示取j个质因子的情况下可以取得最大素数用堆维护g[mx[j]][j]的最大值,
bzoj 3073: [Pa2011]Journeys 注意是无向图。线段树优化连边跑最短路。#include#include#include#include#include#define ll long long#define inf 1e9#define eps 1e-8#define md#define N 5000010using namespace std;struct yts { int t,ne; bool l;} e[130
bzoj 2140: 稳定婚姻 查询二分图每一条边是否一定在二分图最大匹配上:首先任意一个最大匹配,然后把两个匹配点缩成一个点,然后用这个图跑强连通分量,如果一个点所在的强连通分量大小大于1,那么说明原图存在一条匹配边-非匹配边-匹配边-非匹配边的环,所以这些边不一定在最大匹配上。#include#include#include#include#include#define ll long long#define
bzoj 2162: 男生女生 二分图最大团=补图最大独立集,因为这道题是人数多为第一关键字,男生多为第二关键字,所以男生的权值设为n+2,女生设为n+1连边S->x flow=n+2x->y+n(xy之间没有边) flow=infx+n->T flow=n+1然后总人数是ans/(n+1),男生是ans%(n+1)发现任选一种,图都是一样的,A个男生向B个女生的每个都有边。容斥,另表示i个男生j个女
bzoj 4111: [Wf2015]Keyboarding 傻逼广搜,我却想不出来.f[i][j][k]表示位置ij,打完第k个字母的最少步骤,然后这个题卡内存,用动态内存或者压着内存开数组.以后如果再看到网格图的题,要想到与每个点连边的只有4个.#include#include#include#include#include#define ll long long#define inf 1e9#define eps 1e-8#
bzoj 4499: 线性函数 0没有逆元!0没有逆元!0没有逆元!重要的事情说三遍!把query的式子展开就是0没有逆元!0没有逆元!0没有逆元!重要的事情说三遍!把query的式子展开就是首先是一个看上去很对的做法:另d[i]=PI[j=i to n] k[i]那么答案就是用线段树维护d,维护b[i-1]*d[i]的区间和就可以了。最后答案*d[r+1]^(
bzoj 4456: [Zjoi2016]旅行者 分治+最短路离线,分治,每次查询起点终点都在[x1,x2][y1,y2]内的答案。接下来讨论x2-x1>y2-y1的情况,反之类比即可。现在我们要计算的是路径范围在这个矩形之内,且路径经过中轴线的答案。枚举中轴线上的每个点,计算它到矩形内的点的最短路,然后用dis[a]+dis[b]更新询问的答案。之后分治查询两个点在中轴线同一边的答案。这样做为什么是对的?在分治的过程中,
bzoj 4444: [Scoi2015]国旗计划 破环成链,对于每个点的策略是找最后一个能传递到的旗手,每个点都指向一个特定的点,这样形成了一棵树。如果father[x]传递到的最后一个点是y,那么x传递到的最后一个点在x到y的路径上,所以如果把一条链看成一段决策,那么决策点所在的深度是不减的。所以可以对树进行dfs,维护一个双端队列,每次暴力进出队列,然后ans=dep[y]-dep[x]+1。复杂度O(n)还有一种倍增的写法:
bzoj 4455: [Zjoi2016]小星星 一种暴力做法是f[x][y][S]表示以i为根的子树,x匹配的是y,使用了的集合是S的方案数,然后转移显然,然而我并没有想到。正解非常巧妙。枚举集合S,要求所有点只能和S中的点配对,可以多个点匹配一个点,f[x][y]表示x匹配的是y,以x为根的子树的方案数,转移yy一下就行。然后容斥 如果|S|&1 == n&1 那么ans+=sum 否则 ans-=sum这道题告诉我,遇到枚举
bzoj 4402: Claris的剑 要求本质不同,考虑字典序最小的排法序列是这样的:1(212121……)2(323232……)3(434343……)…… m或者1(212121……)2(323232……)3(434343……)…… m m-1这两种是没有交集的,因为在确定m的值之后,序列长度的奇偶性也就确定了。每个序列相当于 1 2 3…… m (m-1) 在第1到m-1个间隙插入任意个数对(i+1,i
bzoj 4454: C Language Practice O(n)-O(1) gcd O(n)-O(1) gcd数n的质因数分解最多只有一个数大于sqrt(n),且那个数一定是素数一个数一定可以分解成三个数相乘,每个数于是,我们可以通过O(n)的预处理,以O(1)的效率回答两个数的Gcd计算0~sqrt(n)之间的数两两的gcd,1到n的三个数相乘的分解。然后计算两个数的gcd枚举一个数的这三个因数,设枚举到的数是x如果x否则,x是个质数,只要看另一
bzoj 4421: [Cerc2015] Digit Division 显然是找前缀为0的断点个数,注意如果全局答案不是0,那么ans=0下面是简单的证明(kouhu)首先,证明只有前缀为0的位置可以成为断点。第一段显然前缀只能为0假设前k段前缀只能为0,那么第k+1段一定满足 (f[k+1]-f[i]*10^(k-i))%m=0,由于f[i]%m=0,所以f[k+1]%m=0;所以只有前缀为0的位置可以成为断点。之后证明任意两个断点之间都是合
bzoj 4448: [Scoi2015]情报传递 首先想到实际上是查询链上开始搜集的日子小于x的点的个数,然后yy了树上莫队做法。其实这就是树上主席树的 裸题。#include#include#include#include #define ll long long#define inf 1e9#define eps 1e-8#define md#define TR 4000010#define N 200010using nam
bzoj 4401: 块的计数 水题 水题,想麻烦了一点点我的思路:显然只有sz|n时才有可能合法,一个数的约数个数时O(logn)的,所以可以暴力dp题解:其实,当且仅当一棵子树的sz[z]是块的大小的倍数,这个子树的根可以成为一个块的根,所以枚举一下答案暴力就行。#include#include#include#include #define ll long long#define inf 1e9#defi
bzoj 3307: 雨天的尾巴 卡常数+卡内存,如果离散化了应该能好很多,但是我犯逗没有这么做首先如果是序列上在一段内加入一个数,那么就是在位置l +1,在位置r -1,然后用权值线段树维护最大值就行。那放在树上呢?dfs+线段树合并,这个做法好像可以解决很多在序列上按照奇奇怪怪方式扫描并维护奇奇怪怪的东西,然后搬到树上的问题。如果不是用线段树的维护,也可以启发式合并这么搞。在x,y打上+1,lca(x,y) f
bzoj 4522: [Cqoi2016]密钥破解 数论模板大集合#include#include#include#include #define ll long long#define inf 1e9#define eps 1e-8#define mdusing namespace std; ll mul(ll a,ll b,ll p){ ll ans=0; while (b) { if (b&1) ans=(ans+a)%p;
bzoj 4521: [Cqoi2016]手机号码 f[i][j][012][k][s][d]表示前i位,开头为j,(有k-1位相同,是否已经出现3位相同), 出现48的状态为s,压位/不压位的方案数由于11位不含前导0,不用写不足len位的dp又写成 f[.....][i==a[i]]++ 应该是 f[....][i==a[1]]++#include#include#include#include #define ll long
bzoj 4519: [Cqoi2016]不同的最小割 读错题了,注意最小割树是针对无向图而言的。然后就是裸题。#include#include#include#include#include#define ll long long#define inf 1e9#define eps 1e-8#define md#define N 900using namespace std;set st;struct yts { int x,t,f,ne
bzoj 3451: Tyvj1953 Normal 只想到了要单独考虑每个点的贡献如果x是x到y路径上第一个被删除的点,那么对答案有1的贡献所以总共的答案就是所有点对的1/dis(x,y)注意dis(x,x)只算一遍这个可以用点分治+fft解决。#include#include#include#include #define ll long long#define inf 1e9#define eps 1e-8#define
bzoj 3119: Book 单独考虑每个+或-对答案的贡献,会发现第i个位置+A对和的贡献是(n-i+1)*A所以联立方程组ax-by=M-n*Xx+y=n*(n-1)/2解出x和y然后把x和y用1~n-1的数不重复的和表示出来,从n-1到1枚举,用较大的数就行。#include#include#include#include #define ll long long#define inf 1
bzoj 4500: 矩阵 开始以为建出图来搞高斯消元,然后把每个数线性表示写出来。看题解发现想复杂了,直接任意构造解就行了。对于限制条件a[1]+b[1]=c[1]a[2]+b[1]=c[2]a[2]+b[2]=c[3]a[1]+b[2]=c[4]这4个式子,(1)+(3)-(2)就是式子(4),所以还相当于3个式子,可以任意解#include#include#include#inc
bzoj 4504: K个串 求全局第k大,k比较小,不难想到要找到当前最大的数之后去拓展几个小一点的数。用主席树维护右端点是每个数时左端点的答案,发现加入一个数后更改的是[pre[i],i]连续的一段开始我自己想,把根节点加入堆中,然后每次加入它的两个儿子节点,如果l==r就是答案,但是这样很难处理答案为负数的情况实际上,堆中维护的是五元组(root,l,r,id,mx)表示现在的右端点是root,当前代表的区间
bzoj 3667: Rabin-Miller算法 模板题,但是感觉mul这个函数可能有问题。要不是数据范围是10^18,写快乘就行了。#include#include#include#include #define ll long long#define inf 1e9#define eps 1e-8#define mdusing namespace std;ll mx;ll mul(ll a,ll b,ll p){ ll
SDOI2016r1游记 做梦一般,SDOIR1就过去了,成绩不错,但总有一些小的细节不是太如意。Day0早上10点的火车,在车上和同学聊了一些奇奇怪怪的题,就到了济南,然后报道。感觉自己整个人都hai起来了。晚上写了一道题,背背板子,就睡觉了。Day1抽签,发现我们学校只有我,Oxer,davidxu在第二考场,但是感觉外校的神犇好多呀。进入考场,敲完头文件、对拍之后就不知道干什么了,干坐了10分钟,
WC2016——还是认真练码力吧 从绵阳回来也好几天了,一直不忍心面对自己烂成狗的比赛成绩,但是该总结还是要总结的,顺便列一列之后的计划游记第一次去四川,走之前一个月就缠着老师说要去成都爽一发,然后就去吃了好多好吃的,也发现自认为不能吃辣的我还是蛮能吃的。老师推荐的辣牛肉,超级够味的成都火锅,尤其是白菜!!!还有很多甜品:三大炮,菠萝饭,还有很多叫不上名字的好吃的。最好玩的是那里的东西都愿意加上个姓,例如赖汤圆、钟水饺,还
bzoj 3689 异或之 二分答案+trie判定。卡时过之后看题解:用堆维护每个数可以获得的最小答案,每次取出最小元素,查询它的比当前大的最小值,加入堆。就和dijstra求k短路差不多的思路。#include#include#include#include#include#define ll long long#define eps 1e-10#define md#define N 4000
bzoj 4012 [HNOI2015]开店 【树链剖分】 这道题好像各位神犇都是用动态树分治写的,我这么弱只能用树剖水一水了。dis(x,y)=dis(1,x)+dis(1,y)-dis(1,lca(x,y))前两个都是定值,求第三项就行了。每个点x维护不在重链上的子节点的个数*dis(1,x),查询显然,再yy一些别的东西就可以了。#include#include#include#include#include
bzoj4008[HNOI2015]亚瑟王 f[i][j]表示给[i,n]区间的卡牌j次机会的概率。单独考虑每一张牌的情况,而不是单独考虑每一轮的情况f[0][r]=1;f[i][j]=f[i-1][j]*sig(i-1,j)+f[i-1][j+1]*(1-sig(i-1,j+1))其中sig[i][j]表示第i张牌,j次机会,都没有发出去的概率。注意数组清0#include#include#include#inc
bzoj 3535Fair Photography【hash】 很容易想到枚举出现的位置,哈希一个前缀和,判定有无出现过。这样复杂度有点大。hzwer给出了一个小的常数优化:维护每个数和第一个出现的数的差值,这样只有改首个复杂度是k^2否则都是O(k)注意细节#include#include#include#include#include#define ull unsigned long long#define inf 1e9#
bzo j3122: [Sdoi2013]随机数生成器 这道题不难想,难的是分类讨论。先是最一般的情况推出公式套用bsgs。 这个要求答案>1且a!=1(等比数列的分类讨论)且a!=0(0没有逆元)所以第一种情况a!=1 a!=0 ans=1第二种情况 a!=1 a!=0 ans!=1如果a=1,第一种情况ans=1第二种情况 ans!=1 b=0 (0没有逆元)第三种情况 ans!=1 b!=0如果a=0,a1=t
bzoj 4295 Hazard 【循环】【单调队列】【扫描】 第i个人抽到的序列与(i%m)是一样的,所以只需要讨论i%m剩余系下的问题。首先搞出来每个人抽牌的循环,然后我们要判定这个人需要多少个循环加多少轮才能没钱。需要知道两个东西,一个循环中最小的前缀和和一个循环的和。这样循环数就大约是(初始钱数-最小前缀和-1)/一个循环的和+1,还需要的轮数就是跑完循环之后第一次到0的轮数。现在考虑维护方法:(我比较弱,这些想了好久)先复制一次,循环
bzoj 1567 JSOI2008]Blue Mary的战役地图【二维字符串哈希】【水题】 二分后判定有无两个相同的子正方形,复习了一下二维字符串哈希。#include#include#include#include#include#define ull unsigned long long#define inf 1e9#define eps 1e-10#define md#define N 55#define H 100010 using namespace
bzoj 2728 与非 【找规律】 【位运算】 【数位dp】 通过与非运算可以组合出and和not,然后and和not可以组合所有的逻辑运算。所以只要有可能,没有表示不出来的数。但是如果所有数都满足st[i]=st[j] 那么这两位无论如何都相等。并查集维护所有相等的类别,数位dp还是不太熟练。01数位dp的本质是枚举所有的非0位,假设它是0,更新答案,然后把它设为1,求之后的答案。#include#include#include#in
bzoj 1398 项链 【最小表示法】 盗CA爷的题,学习了最小表示法,最后发现CA爷不是写的这个算法。但不管了。最小表示法大致是维护两个指针ij且i!=j 把它们向后扫,直到st[i+k]!=st[j+k] 然后将st较大的那个指针移到x+k+1,如果两个指针相等,任取一个加一。 注意是一个循环字符串,在k=l时退出。因为vijos上没有JUDGE_ONLINE 这个宏,wa了半天。#include#include
bzoj 2732 射箭 【抛物线】 【线性规划】 【半平面交】 从原点射出的抛物线方程y=ax^2+bx 注意没有c,开始绕了很久。于是乎可以得出一些线性规划方程 y1=)x1^2a+x1b 其中ab为要求的量。所以二分,用半平面交判定交是否为空。1、半平面交是否为空R-L>1; 及如果有两个及以上向量,不为空2、加4个边框注意方向,而且注意让交点在框内,而不是保证大于系数就行3、题目很坑,要longdouble 而且加上fcmp就错了。#
bzoj 2306 幸福路径 【floyd】【dp】 期望值最大的dp,转移有环开始在想强连通分量缩点之后,块内高斯消元+拓扑图dp。但是高斯消元没有max的转移。所以用了处理有环最大值的方法:floyd总结一下:处理转移有环的方法:最短路(单源 floyd)主要是求max/min高斯消元 主要是求期望。强连通分量缩点 主要是题内有明显提示或强连通分量内部有特殊性质。#include#include#inclu
bzoj 4318 osu 【三次方问题】【dp】 二次方的问题可以说是经典了,三次方yy一下也就出来了。(x+1)^3=x^3+3x^2+3x+1所以维护x^2 x的期望值。注意x^2的期望值不等于x期望值的平方。#include#include#include#include#include#define ll long long#define inf 1e9#define eps 1e-10#define md#d
heheda练数据结构 联赛结束,自己的码力已经下降了不知多少个档次,再加上最近空闲时间比较多,我就开启了这个可以说最费时间的专题。//话说我未完成的数论专题还会继续的。最近看了以下知识点:线段树套线段树线段树套平衡树准备学习:替罪羊树块状链表复习:树链剖分树状数组套线段树一些高级的线段树可持久化tire可并堆bzoj 2957 楼房重建给定第一象限的n
蒟蒻的noip2015滚粗记 oi就是一场实力与运气的博弈——题记 也不知道这会不会是自己的最后一年noip,也不知道2016夏绵阳见是什么样子。但是,第三年的noip,还是值得回味的。Day 0 又是一个阴雨连绵日,和往常不一样的是我弃掉了周五上午的课,回家学(tui)习(fei)。花了一个小时交上了屯题,在学校群里装了装逼。喝了一大碗羊汤,就出发了。 在车上,我们一对一对
bzoj 2039 人员雇佣 2个月没写网络流,已经忘得干干净净了。经典最小割建模 x y 都选 B+D=ax+ay不选x, 选y A+D+F=ay+3exy选x,不选y B+C+E=ax+3exyx,y都不选 A+C=2exy这个东西我列错了3遍,两个选一个没有的是x对y,y对x的贡献和x对y的影响都不选是exy*2开始的时候忘要加双向边了。然后我光荣的写了 put(x,y,f); put(y,x,-f); 竟然过了7个点
bzoj 3997 组合数学 最小链覆盖等于最大独立集。两个点不相互可达则一个数在另一个数的左下角,dp即可。#include#include#include#include#include#define ll long long#define inf 1e9#define eps 1e-10#define md#define N 1010using namespace std;ll f[N][N],a[N][N];int m
heheda的数论专题练习 膜拜sd数论之神yts1999bzoj 2956 模积和这是bzoj第300道题,纪念一下再说其实并不难,把n%i变成n-(n/i)*i,然后不考虑i!=j就是n^2*m^2-n^2*sigma( (m/j)*j )-m^2*sigma( (n/i)*i )+sigma(i*j*(n/i)*(m/j)) i是从1到n枚举,j是从1到m枚举减去i=j情况n^2*m-n*sigma( (m/i)*i
bzoj 1818/1732 聚会 首先,答案的点一定在三组lca中的一个上它在那个最深的lca上,不要问我为什么或者,这三组lca一定有两个重复的,答案是那个不重复的。#include#include#include#include#include#define ll long long#define inf 1e9#define eps 1e-10#define md#define N 500010using namespace
bzoj 3594 方伯伯的玉米田 开始觉得自己好不容易想出一道题,后来发现自己是错的。用f[i][j]表示前i个玉米,发动j次技能最多能留下的玉米数。但是这个东西可以由j=1~i-1中任意一个数转移来,所以用树状数组优化dpf[i][j]=f[p][q]+1(p=p+q)#include#include#include#include#include#define ll long long#define inf 1e9#defin
bzoj 2734 集合选数 构造矩阵1 3 9 27…2 6 18 54…4 12 36 108………每个数是上面的数乘2,左面的数乘3。这样进行状压dp就是相邻的格子不能选的方案数。如何判断一个二进制数没有两个连续的1? x&(x如果有的数没有出现过,就以它为左上角元素再构造一个矩阵。这是怎么想到的?!!#include#include#include#include#include#define ll long lo
bzoj 2054 疯狂的馒头 想到了要用一种东西维护下一个没被染色的是什么东西,但是没想到是并查集。这道题就相当于在每一个集合里的数都会跳到一个相同的点,就相当于并查集的代表元素。如果将一个点染色,就把它的父亲设为i+1,这样并查集的代表元素就是下一个没有被染色的点。#include#include#include#include#include#define ll long long#define inf 1e9#defin
bzoj 2121 字符串游戏 BX正在进行一个字符串游戏,他手上有一个字符串L,以及其他一些字符串的集合S,然后他可以进行以下操作:对于一个在集合S中的字符串p,如果p在L中出现,BX就可以选择是否将其删除,如果删除,则将删除后L分裂成的左右两部分合并。举个例子,L='abcdefg' , S={'de'},如果BX选择将'de'从L中删去,则删后的L='abcfg'。现在BX可以进行任意多次操作(删的次数,顺序都随意),他想