自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(52)
  • 收藏
  • 关注

原创 CF1060E Sergey and Subway

考虑原图:对于原图中一条长度为偶数len的路径,新图长度为len/2;对于原图中一条长度为奇数len的路径,新图长度为(len+1)/2。设原图长度为偶数的路径总长为A,长度为奇数的路径总长为B,长度为奇数路径有C条,那么新图路径总长即为:(A+B+C)/2。A+B即为原图的所有路径总长,算每一条边的贡献可得。C为原图奇数路径条数,可以发现,一条奇数路径的两顶点的深度,一定是一奇一偶。#include <bits/stdc++.h>#define int long longusing

2020-09-30 00:18:33 150

原创 CF868F Yet Another Minimization Problem

对于暴力dp的状态以及复杂度瓶颈就不再描述,假设前置内容大家都会了。f[j][i]:前i个分了j组的最小费用。记calc(l,r)表示:[l,r]分为一组的费用。对于这个dp方程,我们可以得到一个性质,若:f[j][i]=f[j-1][p]+calc(p+1,i),f[j][ii]=f[j-1][pp]+calc(pp+1,ii),则i<=ii。(不会证明,只能说是多画点图后猜测的…,当然,也蛮显然的)而这个就是决策单调性优化dp的标志了。总而言之就是:由于刚刚猜测的式子,所以当我们做当前的

2020-09-29 18:54:16 173

原创 CF487B Strip

#include <bits/stdc++.h>using namespace std;const int N=1e5+5;int n,s,l,inf;int a[N],LOG[N],minn[N][18],maxn[N][18],f[N];inline int query(int l,int r){ int s=LOG[r-l+1]; return max(maxn[l][s],maxn[r-(1<<s)+1][s])-min(minn[l][s],minn[r.

2020-09-29 16:30:04 162

原创 Codeforces Round #674 (Div. 3)

A.Floor Number对于第一层要分开来算;当不整除时注意加一。#include <bits/stdc++.h>using namespace std;int T;int n,x,ans;int main(){ scanf("%d",&T); while (T--) { scanf("%d%d",&n,&x); n-=2; ans=1; if (n<=0) { printf("%d\n",ans); contin

2020-09-29 07:53:22 422 1

原创 CF1092E Minimal Diameter Forest

和CF455C Civilization貌似挺像。我们求出每棵树的直径和中点,找到直径最大的树后,将别的树的中点与直径最大的树的中点相连,即可完成构造。#include <bits/stdc++.h>using namespace std;const int N=1e5+5;int n,m,u,v,ans,p,mid,pos;int f[N];bool vis[N],jay;int cnt,head[N];struct edge{int next,to;}e[N<<

2020-09-28 23:50:34 306

原创 CF461B Appleman and Tree

感觉这题的dp挺神奇的,不是特别显然…所以也不会什么递推式的证明…#include <bits/stdc++.h>#define int long longusing namespace std;const int N=2e5+5,MOD=1e9+7;int n,u,v;int f[N][2],a[N];int cnt,head[N];struct edge{int next,to;}e[N<<1];inline void add(int u,int v){

2020-09-28 11:29:07 118

原创 CF478D Red-Green Towers

考虑a+b的最优情况,那么最大层数刚好为:sqrt(2*(a+b))。有可能由于a与b相差较大,则不能到达这个理论最大层数,但是没有关系,我们在dp过程中,保证当前每一步的转移是合法的,则最后倒序枚举合法的最大层数即可。对于dp状态的解释,写在了注释中。#include <bits/stdc++.h>#define int long longusing namespace std;const int N=4e5+5,MOD=1e9+7;int a,b,n;int f[2][N],

2020-09-27 22:37:29 185

原创 Atcoder ACL Beginner Contest

D.Flat Subsequencef[i]表示:数列最后一个为第i个的最大值,它可以由之前的,数值差绝对值在m以内的若干个f[j]转移而来。所以我们用一棵线段树,在a[j]的位置上把f[j]存下来,然后对于第i个值来说,只要查询:[max(a[i]-m,0),min(a[i]+m,300000)]区间内的最大f值即可。#include <bits/stdc++.h>using namespace std;const int N=3e5+5;int n,m,l,r,mid,ans;

2020-09-27 21:51:35 289

原创 9.22记

针对某神仙说的“写无聊的题解”这一言论,我是这样想的:尽可能地把自己之前写的题,都记录到CSDN上来,而对于某些较简单的题,题解自然也就几句甚至一句话带过了。毕竟这也是自己两年学习的点滴,想在AFO前,尽可能地多留下一点痕迹,说不定以后哪天自己有兴致了就会随便翻翻呢?也说不定某篇只有几句话甚至一句话的题解,被某位oier看到后觉得有学习价值,哪怕只是一点,那也是好的。所以最近自己写的题,只要有时间,基本都会放到CSDN上来。至于之前的,可能就得咕咕咕了。...

2020-09-22 21:07:22 117 1

原创 Connected Components

对并查集做前后缀和。对于并查集的前后缀中的节点i来说,如果它在前缀后所属的连通块与它在后缀中所属的连通块不同,那么说明i就是前后缀两个不同连通块的连接点,所以可以把前后缀的两个不同连通块,并为同一连通块。之后就是求连通块个数即可。#include <bits/stdc++.h>using namespace std;const int M=1e4+5,N=505;int n,m,xx,yy,ans,q,x,y;int u[M],v[M],l[M][N],r[M][N],f[N];

2020-09-21 20:37:39 394

原创 [NOI2016]区间

我们只需要关注需要的线段中的最大值和最小值即可,所以若存在若干条不相关的线段,但长度在最小值与最大值之间,那么它不会对答案产生影响,所以我们把这样的不相关的线段全部放进去也没有任何关系。考虑可以用尺取法。按照线段长度排序后,设连续的一段线段的左右端点为i和j,根据两端点中的全部线段是否有至少m条拥有一个同样的点来移动i和j。如何判断两端点中的全部线段是否有至少m条拥有一个同样的点呢? 线段树进行区间累加并维护区间最大和。注意对坐标进行离散化。应该算是最套路的NOI题了吧…#include &lt

2020-09-21 20:28:14 120

原创 [POI2013]LUK-Triumphal arch

二分枚举答案后,做一个可行性dp来检验。#include <bits/stdc++.h>using namespace std;const int N=3e5+5;int n,u,v,l,r,mid,ans;int f[N];int cnt,head[N];struct edge{int next,to;}e[N<<1];inline void add(int u,int v){ cnt++; e[cnt].next=head[u]; e[cnt].to=v

2020-09-21 20:20:49 134

原创 Noip2019 括号树

f[i]表示:以i结尾的合法序列的个数。我们用栈来记录’(‘的位置,对于当前出现的一个’(’,我们将它放入栈中;对于当前出现的一个’)’,如果栈为空,则无贡献,如果栈不为空,则可得:f[i]+=f[fa[sta[top]]]。因为f[i]表示以i结尾的合法序列的个数,所以最后需要将以i节点的若干个祖先节点为结尾的合法序列的个数,累加至f[i]中,即:f[i]+=f[fa[i]]。#include <bits/stdc++.h>#define int long longusing nam

2020-09-21 20:19:33 212

原创 CF427C Checkposts

记录每个强连通分量中,最小值与最小值个数。#include <bits/stdc++.h>#define int long longusing namespace std;const int N=3e5+5,MOD=1e9+7; int n,m,u,v,ans1,ans2;int now,top,col,dfn[N],low[N],sta[N],color[N],minn[N],sum[N],a[N];int cnt,head[N];struct edge{int next,to

2020-09-21 20:15:21 138 1

原创 CF1000E We Need More Bosses

对无向图进行缩点后求树直径即为答案。#include <bits/stdc++.h>using namespace std;const int N=3e5+5;int n,m,u[N],v[N],ans,p;int now,top,col,dfn[N],low[N],sta[N],color[N];int cnt=1,head[N];struct edge{int next,to; bool vis;}e[N<<1];inline void add(int u,int

2020-09-21 20:14:13 164

原创 CF490F Treeland Tour

以每个点为起点,做一次朴素的nlogn复杂度的lis,共n个点做n次,总复杂度:O(n^2 log n)注意树上操作时的还原操作。#include <bits/stdc++.h>using namespace std;const int N=6e3+5;int n,u,v,ans;int a[N],f[N];int cnt,head[N];struct edge{int next,to;}e[N<<1];inline void add(int u,int v){

2020-09-21 20:12:30 221

原创 CF356A Knight Tournament

对m个操作倒序进行操作,利用线段树实现区间赋值。#include <bits/stdc++.h>using namespace std;const int N=3e5+5;int n,m;int l[N],r[N],x[N],sum[N<<2],add[N<<2],ans[N];inline void pushdown(int k){ if (add[k]) { sum[k<<1]=sum[k<<1|1]=add[k];

2020-09-21 20:10:15 159

原创 CF999E Reachability from the Capital

对于缩点后得到的DAG,我们求出入度为0的强连通分量的个数,即为最少的需要添加的边。(注意判断首都所在的强连通分量的入度)#include <bits/stdc++.h>using namespace std;const int N=5e3+5;int n,m,s,u[N],v[N],ans,du[N];int now,top,col,dfn[N],low[N],sta[N],color[N];int cnt,head[N];struct edge{int next,to;}e[N

2020-09-21 20:08:53 116

原创 CF1120C Compress String

朴素算法n^2求最长公共后缀#include <bits/stdc++.h>using namespace std;const int N=5e3+5;int n,a,b;int f[N],g[N][N];char str[N];int main(){ scanf("%d%d%d",&n,&a,&b); scanf("%s",str+1); for (register int i=1; i<n; ++i) for (register int

2020-09-21 20:05:02 177

原创 [JSOI2007]字符加密

将字符串进行复制,后缀排序后,对sa[i]进行查找。若sa[i]<=len,则输出s[sa[i]+len-1]即可。应该算是SA最裸的题了,不需要求height。#include <bits/stdc++.h>using namespace std;const int N=2e6+5;int n,m,len;int sum[N],rk[N],rk2[N],tp[N],sa[N],height[N];char s[N];inline void qsort(){ for

2020-09-19 09:00:17 910

原创 [USACO06DEC]Milk Patterns G

我们想要得到一个:至少出现k次的子串的最长长度。后缀排序后可得:含有这个"出现k次的子串"的后缀,必定是连续的,且前若共有k个连续的后缀拥有这个“出现k次的子串”,那么他们连续的区间一段lcp的最小值,一定就是这个“出现k次的子串”的最大值了。所以,求出height以后,找出:区间长度为k-1的区间的最大的最小值。单调队列或二分求解。由于本菜菜单调队列还是会的(单调栈实在恶心),所以就偷懒写这个码量较小的了…#include <bits/stdc++.h>using namespac

2020-09-18 20:29:35 220

原创 [AHOI2013]差异

两个后缀i,j的lcp,其实就是:min(height[k]) ,i+1<=k<=j。所以这一部分的总和就是:height数组[2,n]内,每一区间的最小值之和。考虑用二分+ST表来求和。暴露了菜鸡不会写单调栈的事实…#include <bits/stdc++.h>#define int long longusing namespace std;const int N=5e5+5;int n,m,ans;int sum[N],rk[N],rk2[N],tp[N],s

2020-09-18 20:20:10 134

原创 洛谷 P2408 不同子串个数

我们可以想到这样的一种计数方法:后缀[n,n]:有多少个不同串后缀[n-1,n]:有多少个不同串后缀[n-2,n]:有多少个不同串…最后答案减去重复的串。(发现无法统计答案)那么改变一下顺序,将这些后缀按照字典序排序后,我们也可以得到另一种顺序来进行计数:字典序第一小的后缀:有多少个不同串字典序第二小的后缀:有多少个不同串字典序第三小的后缀:有多少个不同串…我们可以发现,排序以后的,i从2开始,第i个串和第i-1个串,他们相同的串的个数,就是height[i]。而初始,串的个数一共为

2020-09-18 20:13:56 261

原创 生日

幼稚园文笔,预警…17周岁了都说生日会开心,要庆祝,我庆祝的方式好像只是打了4盘游戏,而且还都输了。其实蛮伤心的说实话17年了,还是这样的碌碌无为,看着学弟们意气风发,在OI场上奔驰。而我,老得只能在一旁默默观赏他们的跑姿。多么希望去年的我可以再多努力一些啊~人间却没有后悔药、只能寄希望于18岁的生日了。愿能过完充实的17岁,在成年前,送给自己一份满意的成年礼。------走召小朋友...

2020-09-18 20:05:21 882 1

原创 洛谷 P3809 【模板】后缀排序

基数排序因为每次只有我们所谓的“第一关键字”和“第二关键字”,所以是一次排序复杂度为O(2n),对len进行倍增,所以只要进行log n次排序。所以总复杂度:O(n log n)。#include <bits/stdc++.h>using namespace std;const int N=1e6+5;int n,m;int rk[N],rk2[N],sum[N],tp[N],sa[N];char s[N];inline void qsort(){ for (register

2020-09-16 20:44:40 112

原创 [HNOI2013]比赛

加了一堆不改变分数的没用剪枝以后,才发现这题是可以记忆化的…对于若干个人,如果这若干人的现有分数,在之前出现过,那么就直接把之前的记忆化的值拿来用就好了。一个人最多比9场,最多获得27分,所以我们可以用一个28进制的数,来表示:当前剩下的人,剩下的分数的状态。这个值,可以用map来存储。注意map查找时用find函数,因为有可能这种情况之前遇到过,但是答案为0,而find函数对于赋值过但是值为0也可以表现。#include <bits/stdc++.h>#define int long

2020-09-15 22:39:56 116

原创 [POI2011]KON-Conspiracy

根据2-SAT模型建边后,可以得到两个组分别是:一个团和一个独立集。之后需要思考的就是有多少种不同的方案数。我们发现,对于团和独立集,我们每次只能最多各自拿出一个点,放到对方中去(当然可以不拿)。而由于n恰好满足n^2的数据范围,所以,我们枚举从团中拿出放到独立集中的点,和从独立集中拿出放到图那种的点,n ^2判断操作后是否能满足条件即可。#include <bits/stdc++.h>using namespace std;const int N=5e3+5;int n;bool

2020-09-14 11:57:08 183

原创 UVA1391 Astronauts

每个宇航员只能根据年龄情况,分配A,B中的一个任务,和C任务。考虑两个有矛盾的宇航员:1.如果他们在不同年龄区段,那么他们只要不同时在C即可。(即,若其中一人在C,另一个必须在A或B)2.如果他们在同一年龄区段,那么,当其中一人在A或B时,另一人必须去C。多了两个限制条件。#include <bits/stdc++.h>using namespace std;const int N=1e5+5;int n,m,x,y,sum,a[N];int now,top,col,dfn[N*

2020-09-14 11:44:04 149

原创 [HNOI2010]平面图判定

根据哈密顿回路的顺序,建立虚拟坐标,后根据虚拟坐标判断两不在回路上的边是否相交。若相交,则两条边必须:一条在内一条在外。根据2-SAT建边即可。注意边数为10000,但根据平面图性质,m<=3*n-6,所以对于边数不满足性质的情况,直接判断不可行。#include <bits/stdc++.h>using namespace std;const int N=605,M=8e5+5;int T,n,m,tot,a[10005],b[10005],c[N],id[N],vec[N];

2020-09-14 11:39:59 1010

原创 UVA1146 Now or later

二分枚举答案,2-SAT检验是否可行。#include <bits/stdc++.h>using namespace std;const int N=2e3+5;int n,l,r,mid,ans,tot,a[N*2];struct number{int x,y;}num[N];int now,top,col,dfn[N*2],low[N*2],sta[N*2],color[N*2];int cnt,head[N*2];struct edge{int next,to;}e[N*N

2020-09-14 11:35:44 131

原创 [POI2001]和平委员会

建边如下图:#include <bits/stdc++.h>using namespace std;const int N=8e3+5,M=2e4+5;int n,m,x,y;int now,top,col,dfn[N<<1],low[N<<1],sta[N<<1],color[N<<1],fr[N<<1];int cnt,head[N<<1];struct edge{int next,to;}e[M&lt

2020-09-13 12:08:04 274

原创 CF875C National Property

根据2-SAT的方法建图后,得到强连通分量,并根据与拓扑序联系,输出答案。代码中用详细注释。#include <bits/stdc++.h>using namespace std;const int N=1e5+5,M=1e5+5;int n,m,ans,a[N],b[N];int cnt,head[N<<1];int col,now,top,dfn[N<<1],low[N<<1],color[N<<1],sta[N<<1

2020-09-13 10:46:38 205

原创 洛谷 P4782 【模板】2-SAT 问题

2-SAT问题可以通过强连通分量来判断条件是否矛盾。而题目往往会要求输出方案,输出方案时,强连通分量的scc值,会和原图的拓扑序紧密联系在一起。#include <bits/stdc++.h>using namespace std;const int N=1e6+5;int n,m,a,b,nowa,nowb;int cnt,head[N<<1];int col,now,top,dfn[N<<1],low[N<<1],color[N<&lt

2020-09-13 10:30:09 177

原创 CF1373E Sum of Digits

网上的好多题解没有看懂,题解中的一些"显然"的结论也觉得完全不显然…我们如果枚举这个数列的第一个数字的个位,那么,如果存在这个数列的话,是一定可以构造出这个数列的。(因为k<=9,所以数列长度<=10,最多只会进位一次)1.当这个数列不存在进位的时候,且第一个数的最后一位为now时,就可以表示为:a+now,a+now+1,a+now+2, … ,a+now+k。(其中,因为不进位,所以now+k<=9,而a则表示他们相同的 最高位到十位)对于这种情况,知道now,k和n后,就能够求

2020-09-13 04:45:40 253 2

原创 [HNOI2013]消毒

如果只有二维,那么我们建二分图求最大匹配,O(n^2)的复杂度可以实现。而现在是三维,发现不会三分图,好像也没有三分图这个算法…再思考一下对于二维,是否有别的暴力实现方法?我们可以暴力枚举哪些行是被消掉的,然后对于不是剩下的黑点,枚举每一列是否需要再消一次。复杂度:O(2^n*m)由于a * b * c<=5000,可得min(a,b,c)<=17,所以现在我们也可以暴力枚举每一层是否消掉,然后对于没有消掉的层,进行二分图求最大匹配,因为现在三维就变成二维的了。我们将最小的那一维作为立方

2020-09-12 18:49:57 143

原创 [ZJOI2007]矩阵游戏

我们发现同行同列的点无论经过多少次变换仍然同行或同列,所以题目可转换为能不能找到n个互相不同行或同列的点。那么我们用二分图求一下最大匹配即可。#include <bits/stdc++.h>using namespace std;const int N=205;int T,n,x,ans;int match[N<<1];bool vis[N<<1];int cnt,head[N<<1];struct edge{int next,to;}e[N

2020-09-12 18:38:47 490

原创 [HNOI2009] 梦幻布丁

如果每次将数量小的颜色,替换为数量大的颜色,那么由于一个格子,最多被换logn次,复杂度即为O(n log n)。所以,我们就用f[x]记录:每个初始颜色为x的颜色,的当前值为多少。(因为根据sum大小换过了颜色)而对于不同颜色的遍历,我们可以用类似链式前向星(或链表)的东西来存储。#include <bits/stdc++.h>using namespace std;const int N=1e5+5,M=1e6+5;int n,m,opt,x,y,ans;int a[N],f[

2020-09-10 04:54:33 203

原创 [CQOI2010]内部白点

画图后我们发现,新出现的黑点是不会再创造出更新的黑点的,即黑点只会被原有的黑点创造出一次。这样,此题就成了虔诚的墓主人,且不需要计算组合数问题。#include <bits/stdc++.h>#define int long longusing namespace std;const int N=1e5+5;int n,k,aa,bb,size,l,r,ans;int x[N],y[N],a[N],b[N],R[N],cnt[N],sum[N<<2];vector&l

2020-09-09 20:03:05 115

原创 [SDOI2009]HH去散步

题目要求对于同一条边,不能走过去后立刻走回来,所以很明显我们需要把一条边拆成两条来做。此时我们的状态也需要改变:num[i][j][t]表示从第i条边到第j条边,经过时间为t的方案数。因为我们的方案是设第i条边到第j条边,所以初始矩阵赋值时,其实已经过去了一个单位的时间。所以我们只需要,再累乘矩阵T-1次即可。#include <bits/stdc++.h>using namespace std;const int N=130,MOD=45989;int n,m,t,A,B,cnt,

2020-09-09 19:47:37 137

原创 [SCOI2009] 迷路

当边权均为0或1时,我们是num[i][j][t]表示从i点到j点时间为t的方案数,将t拿出来,用矩阵快速幂进行优化,使得复杂度由O(Tn^3)变为O(logT n^3)。那么现在对于边权不同的图怎么办呢?我们将一个点拆为9个点来做。如果点i到点j有一条k的边,那么我们就连一条(i,k)到(j,1)的边。而对于每个点拆成的9个点,在相邻两点之间进行连边。最后,将矩阵累乘T次,用矩阵快速幂优化即可。#include <bits/stdc++.h>using namespace std;

2020-09-09 19:44:09 118

空空如也

空空如也

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

TA关注的人

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