自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

青烟绕指柔的博客

欢迎来到 AR 的博客!

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

原创 AB-string

题目链接:AB-string考虑计算不合法的字符串。我们可以发现形式为:ABABBA______________BA用总方案减去即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>#define int long longusing namespace std;const int N=3e5+10;int n,res; char str[N];sign

2021-01-20 15:20:44 3

原创 Mathematics society problem

题目链接:Mathematics society problem最大数字,可以看成是最大字典序,因为剩下的字符串长度一定。所以我们考虑从高位贪心,判断当前能不能选9,然后不能的话再看能不能选8…依次类推。考虑如何判断:假设我们答案的某个前缀为 99,那么一定是选最前面的两个9最优,所以我们实际上是每次添加一个选的数字。那么这个数字满足最后一次选的数字到这个数字之间的数字可以被全部删掉,并且后面剩下的数字可以满足还要删掉的数字。AC代码:#pragma GCC optimize("-Ofast

2021-01-18 17:10:50 12

原创 [JLOI2015]管道连接

题目链接:[JLOI2015]管道连接我们先对每个特殊点集求出构成一颗斯坦纳树的最小代价。然后对于答案来说,是一颗最小代价的斯坦纳森林。所以我们最后枚举每种集合的斯坦纳树来组合成斯坦纳森林即可。要注意转移的合法性。当前集合要被拆分成几颗不同频率的生成树,并且这些频率的点被全部包含才可以转移。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int lon

2021-01-18 14:54:34 15

原创 Codeforces - Strange Set

题目链接:Codeforces - Strange Set不难看出是一个最大权闭合子图。但是我们考虑优化连边,显然每个点对于同一种权值来说,只会连前面最近的。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int inf=0x3f3f3f3f;const int N=3

2021-01-16 18:55:17 48 4

原创 Codeforces - E. Minimum Path

题目链接:Codeforces - E. Minimum Path不难发现其实就是最大边权变成0,最小边权变成2倍。我们可以假设是可以有一条边免费走,且有一条边要走2倍的一个最短路。其实就是一个分层图或者最短路上dp。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>#define int long longusing namespace std;const int N

2021-01-16 14:42:06 28

原创 完全平方数

题目链接:完全平方数首先可以想到二分。然后我们对于 2 的完全平方数来说,全部计算即可,3也同理。但是对于6来说,被计算了2次,所以需要减去。然后对于4来说,已经被2计算过了,跳过即可。其实我们不难发现,这就是莫比乌斯函数。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>#define int long longusing namespace std;const i

2021-01-14 12:10:02 18

原创 Codeforces - Sum of Paths

题目链接:Codeforces - Sum of Paths不难发现,如果能维护每个点在所有路径上面的点数和,那么对于修改不难维护。所以考虑如何维护每个点的出现次数,我们枚举每个点,然后枚举当前点是路径上面第几个点即可。然后就是两种方案数的乘积,就是从任一点到这个点走 x 步的方案数 * 从这个点走 k-x 步出去的方案数。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>

2021-01-10 15:21:43 29

原创 CTOI10D2 - PIN

题目链接:CTOI10D2 - PIN我们枚举几个位置固定相等,然后其他位置不管,然后算出方案数。但是我们会发现计算重复了,比如3个位置一样会包含4个位置一样的。需要容斥掉。假设对于3个位置一样,因为对于某种3个位置的选择,会多计算一次4个位置的,然后有4种3个位置的,所以减去4倍的4个位置相同的方案数。对于2个位置一样,对于某种2个位置一样的选择,会有2种3个位置的,然后有6中2个位置的,然后3个位置的有4种,所以需要减去 2 * 6 / 4 种3个位置的方案数。其他同理。AC代码:#p

2021-01-06 15:28:30 20

原创 Codeforces - Little Elephant and Broken Sorting

题目链接:Codeforces - Little Elephant and Broken Sorting令 dp[i][j] 为 a[i] > a[j] 的概率。然后对于每次交换:交换位置为x,ydp[k][a] = dp[k][b] = ( dp[k][a] + dp[k][b] ) / 2dp[a][k] = dp[b][k] = 1.0 - dp[k][a]转移很显然。最后 dp[a][b] = dp[b][a] = 0.5AC代码:#pragma GCC optimize(

2021-01-06 10:58:45 25

原创 Codeforces - Vowels

题目链接:Codeforces - Vowels考虑直接维护每个状态的合法个数。考虑使用sos dp维护。那么我们对于每个字符串,只需要对子集容斥一下即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=(1<<24);int n,dp[N],c

2021-01-06 10:14:53 19

原创 Jersey Number

题目链接:Jersey Number直接算有交集的不太好计算,我们可以选择计算不相交的,然后用总方案数减去。考虑不相交的,我们枚举每一种状态的区间,然后因为不相交,所以方案数为当前状态区间的方案数乘以当前状态取反的子集的方案数。对于一个状态的方案数,我们可以枚举右端点,对于左端点合法的一定最多只有16个。然后计数一下即可。对于一个状态的子集个数可以sos dp得到。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#includ

2021-01-06 09:01:52 28

原创 Subset

题目链接:Subset如果没用修改操作,直接sos dp即可。现在有修改,所以我们可以考虑值域分块。对于二进制前8位和后8位分开处理。令cnt[x][y] 为数字前8位为x,后8为的超集为y的个数。那么对于修改操作我们只需要枚举后8位即可。对于查询操作我们枚举前8位即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long long

2021-01-04 15:25:20 19

原创 Codeforces - Jzzhu and Numbers

题目链接:Codeforces - Jzzhu and Numbers考虑反向枚举每个与运算不为0的集合个数,最后做差。然后我们可以枚举每个最后与起来的答案,我们就可以利用容斥来做。先求出每个集合的超集个数,最后利用二进制中1的个数来容斥。当只有一个1的时候减去这个答案,2个1的时候,由于计算了2次所以加上,然后3个1减去依次类推。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h

2021-01-03 20:15:07 52

原创 Codeforces - Bits And Pieces

题目链接:Codeforces - Bits And Pieces我们枚举每个 i ,然后按照二进制高位贪心,如果当前为0才需要管,我们只需要从后面看当前这个需要的二进制集合能否在后面找到二进制与起来,次大的下标。如果满足就加入答案,然后继续看低位。所以我们直接sos dp处理出来每种集合次大的位置。那么与起来也是一定满足的。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h&gt

2021-01-03 12:08:35 29

原创 AT3913 XOR Tree

题目链接:AT3913 XOR Tree每次操作一条链显然不可做,我们尝试利用异或转化为两点间的操作。我们于是可以把边权转化为点权,对于每个点权为相邻边的异或值。然后我们可以发现每次操作一条链只有两个端点会改变。然后对于显然变成两点间的操作,显然对于相同权值的点,贪心只用一次操作即可。否则那么点权都是不一样的,直接状压dp。因为权值很小。令dp[s]为当前的点权集合为s的答案,我们可以发现如果一个集合异或为0那么才是有解的。因为每次异或两个相同的数,整个集合的异或是不会改变的。所以我们单独对集合

2021-01-03 10:57:59 15

原创 Sweet Fruit Chocolate

题目链接:Sweet Fruit Chocolate考虑每个点的贡献即可,每个点如果选取,那么对所有祖先都有贡献,其实就是dep[x]*a[x],然后对于另外 n-1 个点有 2^(n-1)种选法。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=1e6+10,m

2020-12-21 11:44:37 26

原创 Sum of Log

题目链接:Sum of Log因为 i & j == 0 ,所以考虑 i 或者 j 的最高位即可。然后我们枚举每个当前位为最高位,就需要知道当前位的高位全为 0 ,然后后面合法的方案数。最后统计即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>#define int long longusing namespace std;const int mod=1

2020-12-18 15:36:27 85 2

原创 [PA2010]Riddle

题目链接:[PA2010]Riddle不难看出可以使用2-SAT去解决。对于每条边来说,相当于就是某个端点不取,另一个端点必须取。对于每个集合来说,我们就是如果这个点取,那么其他点不能取。但是不能暴力连边。我们可以如下建图:1 < 2 < 3 < 4 < 5 …1 > 2 > 3 > 4 > 5 …分别加上两排点,然后对于某个点取,往前后位置连边即可。因为数据比较大,边很多,所以用vector建图会TLE。pushback次数太多。AC代

2020-12-15 19:56:06 26

原创 Collecting stars

题目链接:Collecting stars首先答案一定是一段连续的区间。然后我们可以发现从 s 开始,我们如果只单向走一定是连续的。如果我们需要两边都到达的话,第一次走的一边一定是跳着走的。两种情况取max即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=

2020-12-10 18:05:16 42

原创 Triangle Numbers

题目链接:Triangle Numbers显然一个非0数字出现3次及以上,那么一定合法。否则每个数字出现次数为0,1,2然后状态压缩之后数位dp即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=13;int a[N],pw[N],l,r,dp[N][3&

2020-12-09 19:40:22 36

原创 Boring Array

题目链接:Boring Array枚举每个数作为最大值。一定不会错过答案的计算。对于最大值来说,一定是尽量扩展包含当前作为最大值的区间。因为增加数字一定不会使答案变劣。所以正反单调栈求出对应的区间。然后对于区间就相当于判断出现数字的种类数是否和区间长度相同。离线fenwick或者莫队即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int lo

2020-12-07 16:54:16 49

原创 [POI2015]WIL-Wilcze doły

题目链接:[POI2015]WIL-Wilcze doły我们可以发现右端点向右移动的时候,左端点也是向右移动的。然后怎么判断当前区间是否合法呢? sum[r] - sum[l-1] - 区间长度为d的max。然后维护区间长度为d 的max,单调队列即可。AC代码:#include<bits/stdc++.h>#define int long longusing namespace std;const int N=2e6+10;int n,p,d,res,a[N],q[N]

2020-12-04 19:36:52 94

原创 Codeforces - Sum

题目链接:Codeforces - Sum我们可以发现一个结论,不可能有多个同时只选了一个不完全的前缀。也就是如果对于某一类物品,我们选了前几个,未选完。另一种物品不可能也是只选了前几个,未选完。因为物品价值是单调递增的,一定可以选某一个选更多使得答案更优。所以我们枚举每一类选了几个即可,然后要维护不选这个物品的最大价值。直接分治背包即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/std

2020-12-02 15:31:29 107

原创 Rencontre

题目链接:Rencontre首先对于树上,一个点到给定三个点的最短距离和为:(dis(x,y)+dis(y,z)+dis(x,z))/2然后对于线性期望,我们可以把这个拆开分别求和。E((dis(x,y)+dis(y,z)+dis(x,z))/2)=E(dis(x,y))/2+E(dis(y,z))/2+E(dis(x,z))/2然后就是求出两两之间的距离和。这个我们直接枚举每一条边的贡献即可。注意求出距离和之后变成期望应该除以两两之间的点个数之积。AC代码: #pragma GCC

2020-12-02 13:36:02 65

原创 Simple AniPop

题目链接:Simple AniPop不难看出可以区间dp。所以我们考虑后面拼接一段,断环成链。然后我们令 dp[i][j] 为区间 [ i , j ] 并且 i ,j 未被消掉的最大价值。然后枚举区间 [ i +1 , j -1 ]最后消掉的位置k做转移。最后不难看出答案就是 a[i] + dp[i][i+n] 的最大值。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>

2020-12-01 13:20:25 79

原创 小清新人渣的本愿

题目链接:小清新人渣的本愿首先对于第一种查询:其实就是对于每个值 a 判断是否存在 a-x 。这个显然可以用bitset维护。对于第二种查询:我们可以化简为第一种查询。a + b = x -> a = x - b 。我们维护 -b 的bitset即可,但是不能维护复赛,所以我们加个足够的权值,最后减去。对于第三种查询:暴力找这个数的因子即可。对于每次找到当前区间的bitset,莫队即可。复杂度:令 c 为值域。 m * ( sqrt( c ) + c / 64 )AC代码:#pra

2020-11-30 15:29:41 114

原创 Codeforces - Yet Another DAG Problem

题目链接:Codeforces - Yet Another DAG Problem因为每个边有一个权值为 (a[u] - a[v])*w,于是我们可以把边拆开,看每个点的贡献。我们可以发现我们对每个点设置 0 -> n-1 的权值一定可以达到最小值。然后对每个点可以建立一个类似于分层图的东西,每条边代表 0 ,1,2,。。。然后对于每个点是否选取也就是这条边是否割掉。然后对于DAG上面的权值大小影响,我们可以对 v 的权值小的点,连向 u 的权值大的点,流量为 INF ,这样就能保证最小割

2020-11-29 22:01:25 103

原创 Delete Prime

题目链接:Delete Prime对每个问题单独考虑。第二个问题就是第k个位置的值,那么我们对当前的n分解,直到当前分解出来大于k了,那么问题转化为第 i 轮被移出的第 j 个数的问题,直接在第 i 轮出去的前缀和上面二分。第一个问题就是 k 是第几个位置,同理每次对n分解,然后求出某次大于k了,那么就是求出数字是第 i 轮,第几个出去的,前缀和预处理即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<

2020-11-28 00:22:35 182

原创 第 k 大区间

题目链接:第 k 大区间因为k很大,显然可以想到二分。利用前缀异或和变成两个点的异或。然后就是枚举每一个后缀,求异或大于某个数的个数。直接Trie上查询即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>#define int long longusing namespace std;const int N=1e5+10;int n,k,a[N],ch[N*32]

2020-11-26 01:43:32 180

原创 美丽的建筑

题目链接:美丽的建筑枚举最大值,正反dp即可,用线段树维护区间max。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>#define int long longusing namespace std;const int N=1e5+10;int n,mx[N<<2],suf[N],res;struct node{int a,b,c;}t[N];#def

2020-11-25 19:08:38 114

原创 老奶奶参加宴会

题目链接:老奶奶参加宴会对于新加的边,显然不能n*n的复杂度去加,我们可以对值排序,然后相邻点连接即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>#define int long longusing namespace std;const int N=3e5+10,M=N*5;int n,m,a[N],s,t,id[N],vis[N],d[N],p[N];in

2020-11-25 18:07:02 133

原创 HDU - 4747

题目链接:HDU - 4747每次枚举右端点,加入一个数字,维护每个位置的mex,显然很复杂。所以我们考虑每次删除一个左端点,维护前缀mex。考虑当前位置的影响,会影响到后面大于 a[i] 的mex,会变成 a[i] ,直到下一个 a[i] ,所以线段树维护区间修改即可,因为答案是单调递增的,所以线段树区间赋值即可,不用segment beats。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/

2020-11-25 00:19:17 126

原创 旅游胜地

题目链接:旅游胜地显然可以二分最小值。然后对于一个点取某个值的时候,对于相邻的点我们有能选或者不能一起选,直接2-SAT即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=2e5+10;int n,m,a[N],b[N],dfn[N],low[N],cnt

2020-11-23 20:47:57 55

原创 广告投放

题目链接:广告投放显然有个直接的dp思路,dp[i][j]前 i 个物品,当前还剩人数为 j 的最大值。但是显然无法通过。我们可以发现,对于一个数字每次除以数字向下取整,一共最多 sqrt 种取值,所以预处理出取值,然后按照刚刚的思路 dp 即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>#define int long longusing namespace s

2020-11-23 20:25:51 44

原创 Codeforces - Two Editorials

题目链接:Codeforces - Two Editorials遇到这种选两个区间的问题,我们一般是分段,然后求一个前后缀最大值然后合并。但是这里区间是不好分开的,于是我们可以按照输入的区间中心点排序。对每个区间的前后缀来合并。因为我们按照中心点排序之后,区间具有某种单调性前面的一定能一起处理,对于后面的区间一定不会影响前面的答案。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.

2020-11-21 21:06:02 115

原创 [HNOI2008]明明的烦恼

题目链接:[HNOI2008]明明的烦恼如果按照树形态dp,是不可做的。我们直接按照purfer序列组合数求即可。看成一个 n-2 长度的序列。对于固定的度,相当于盒子中放球,然后剩下的未定的,相当于从剩下位置中随便放。因为要高精度,所以用的pyAC代码:fac=[1]*(1010)def C(n,m): return fac[n]//fac[m]//fac[n-m]def main(): n=int(input()) a=[1]*(n+10) fac[0

2020-11-20 00:15:38 152

原创 Codeforces - Clique in the Divisibility Graph

题目链接:Codeforces - Clique in the Divisibility Graph水题,令 dp[i] 为第i个数结尾的答案。显然每个数字只能从因子当中转移。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=1e6+10;int n,pos[

2020-11-19 20:28:25 137

原创 [POI2017]Sabotaż

题目链接:[POI2017]Sabotaż有一个很显然的二分做法,二分之后dp,dp[x]为x的节点当中最多的叛徒个数。然后每次只能从子树当中选一个最大值转移。但是要快读卡常才能过。正解:dp[x] 为x节点未背叛的最小比例,然后考虑从儿子当中转移,有两种情况。当前儿子未背叛:dp[to],当前儿子背叛:算出儿子在所有儿子当中的size比例。显然选最小的转移即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include&

2020-11-19 20:01:50 133

原创 线性探查法

题目链接:线性探查法考虑每个值,如果不在本来的位置上,那么一定是之前的位置被填充了,然后我们可以根据当前的位置,和本来的位置推出一个在他之前被填充的区间。然后做一个最小字典序拓扑排序即可。不过对于区间连边是 O(n*n)的,需要线段树优化建图。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace s

2020-11-16 18:40:28 204

原创 迷宫

题目链接:迷宫正向考虑十分麻烦,每个点都有可能会冲突。考虑逆向,每个点从根节点向下走。这样就不会冲突了。然后肯定贪心先走深度大的,对于每个点就是等待的时间+深度。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=1e5+10;int n,a[N],dep[N

2020-11-16 16:19:40 107

空空如也

空空如也

空空如也

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

TA关注的人 TA的粉丝

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