摘要:
显然答案可以理解为有(不是仅有)0对情况-1对情况+2对情况…… 考虑这个怎么计算,先计算这t对情况的位置,有c(n-3t,t)种情况(可以理解为将这4个点缩为1个,然后再从中选t个位置),然后相当于在剩下n-4t的位置上摆上4种东西,且每种东西有数量限制(ai-t个)。 这个东西dp一下即可,用f 阅读全文
摘要:
考虑我的每一次添加操作,要满足:1.该串是t的子串;2.该串不能与下一次的串开头字母构成t的子串。那么,设f[i][j][k]表示拼i次,第i次填入的开头字母是j,第i+1填入的开头字母是k的最短长度。 状态转移方程:f[i][j][k]=min(f[i-1][j][t]+f[1][t][k]),这 阅读全文
摘要:
假设该矩形是aij,那么有a(i,j)=a(i-1,j-1)^a(i-1,j+1)^a(i-2,j),不断递归下去可以发现a(i,j)=a(1,y-x+1)^a(1,y-x+3)^……^a(1,x+y-1)。 那么,对第一行处理前缀和,Si=S(i-2)^a(1,i),即给出了两个数S的异或,只需将 阅读全文
摘要:
对树长链剖分,dp令f[i][j]表示第i个点为根的子树中第j种颜色的数量,直接暴力dfs,对于每个节点,先dfs重儿子并直接继承重儿子的信息,再搜索轻儿子并合并,这样的时间复杂度是$o(nlog_{2}n)$的(当然好像直接不按顺序暴力合并也可以过,数据比较水)。 1 #include<cstdi 阅读全文
摘要:
题意可以理解为加边使原图变为完全图后不含有偶环的方案数(边权为0或1),可以联想到二分图染色,询问完全图的方案数即询问对于每一个点可以选0或1,然后使得1边连接的两点点权相同,0边连接的两点点权不同。 对于第一个联通块,显然已经确定,然后从第一个联通块向每一个联通块中的某一点连0边或1边都可以确定该 阅读全文
摘要:
显然可以写可持久化树套树,然而实际上由于只有一整行的修改和单点修改,并没有一个小矩形的修改,所以可以将其转化到一个序列上,只需要写可持久化线段树就可以了(然而标算是操作树)。 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 阅读全文
摘要:
不断将统计当前这颗子树到之前所有子树的路径并合并,考虑以前的路径为x,当前的路径为y,最终答案即$x\cdot 10^{len(y)}\equiv 0(mod\ p)$,转化为$x\equiv -y/10^{len(y)}(mod\ p)$,对于当前每一个y,查询之前x的个数(用map)即可,注意顺 阅读全文
摘要:
先树链剖分,开一棵线段树维护区间:1.abs的和;2.正数的数量-负数的数量;3.最大的负数。 询问就可以直接处理,考虑修改操作,对于一个区间,如果最大的负数+d变为了正数,就暴力修改下去,否则直接修改1和3两个信息并打上懒标记。因为d是非负的,所以每一个节点最多修改一次,时间复杂度不变。 1 #i 阅读全文
摘要:
考虑对询问分块,对于i<K的询问,暴力处理,时间复杂度为o(Kn);对于i>K的询问,发现答案都小于n/K且满足单调性,那么可以二分出每一段相同的答案,时间复杂度为$o(n^{2}log_{2}n/K)$,取K=1000可以通过。 1 #include<bits/stdc++.h> 2 using 阅读全文
摘要:
不管是否使用技能,发现操作前后所有堆二进制中1的个数之和不变。那么对于一个堆其实可以等价转换为一个k个石子的堆(k为该数二进制的个数),然后就是个nim游戏。 1 #include<bits/stdc++.h> 2 using namespace std; 3 int t,n,ans,a[101]; 阅读全文
摘要:
首先由一个神奇的序列叫做Purfer序列,他可以表示一棵树,且每个节点出现此时为度数-1(因此总长为n-2)。 然后dp,用f[i][j][k]表示用前i个点中的j个点构成了一个长度为k的Purfer序列(当然要符合条件),那么有$f[i][j][k]=f[i-1][j][k]+\sum\limit 阅读全文
摘要:
可以发现如果将根的结果写成多项式,可以发现只需要预处理出f[i][j]表示以i为根的子树j次项有多少个,g[i]表示从n个数中选取i个数相乘的和,就可以通过\sum_{i=1}^{n}f[1][i]\cdot g[i]\cdot (n-i)!$计算。可以发现有递推式:$g[i]=g[i-1]\cdo 阅读全文
摘要:
首先发现结果与需要改变的具体位置无关,只和需要改变的位置的个数有关,因此设f[i][j]表示选取了i个数字异或结果有j个1,只要分析接下来选择的数和这j个1有几个重合即可: 1. 三个数字全部重合,即$f[i][j+3]+=f[i-1][j]\cdot c(n-j,3)$ 2. 有两个数字重合,即$ 阅读全文
摘要:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define mod 1000000007 4 #define N 1000005 5 long long n,ans,mu[N],f[N],t[N],vis[N],p[N]; 6 void xx 阅读全文
摘要:
首先有SG(x,y)=mex(SG(x-a,y-a),SG(x-a,y),SG(x,y-a)),其中SG(0,0)=0,打表发现(1,2)(3,5)(4,7)(6,10)(8,13)……时SG为0(即必败),假设第一项是ai,第二项是bi,很容易发现:1.bi=ai+i,2.ai=mex(bi,bj 阅读全文
摘要:
根据SG函数定义,可以发现当y<x<2y时,SG(x,y)=[SG(x-y,y)=0],即两者一定存在一个0,因此就有SG(x+ky,y)=mex(0,……)>0。 换句话来说,对于一个状态SG(x,y)(x>y),如果$x\ge 2y$即为必胜状态,而当x<2y时直接继续判断SG(x-y,y)这个 阅读全文
摘要:
建立后缀自动机,对于同一个节点,出现次数是相同的(right的大小),同时满足单调性(长度越长出现次数越少),所以只需要考虑最长的串即可。 PS:似乎也并不需要求依次后缀的max,不知道为什么…… 1 #include<bits/stdc++.h> 2 using namespace std; 3 阅读全文
摘要:
有两种方法,第一种直接KMP求出next数组,然后发现这样的重复一定是满足s[0,l)+s[l,r)+s[r,len),其中因为有s[0,l)=s[r,len),那么就有s[0,r)=s[l,len),又因为需要l尽量小,那么r就应该尽量大,即next[len]。 考虑如何判断next是否合法,仅需 阅读全文
摘要:
首先有SG(k)=mex(SG(k/2),SG(k/3)……SG(k/9)),SG(0)=0,通过打表可以发现当$n\in[1,1]\cup [10,18]\cup [163,324]……$,规律大概就是$[18^{k-1}+1,18^{k}/2]$时SG的值为0(即必败),那么只需要判断一下n是否 阅读全文
摘要:
求出后缀数组和height数组,然后二分答案后分组查询,一个块内如果有超过k个那么这个答案就可以。 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 50005 4 int n,m,ans,a[N],b[N],h[N],sum[ 阅读全文
摘要:
求出后缀数组和height数组,然后将这个串反过来写在前面然后枚举中心点并求两边的最长公共前缀即可(一定要加连接符)。 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 200005 4 int n,m,ans,a[N],b[N 阅读全文
摘要:
求出后缀数组和height数组,然后因为子串即后缀的前缀,考虑不断新增后缀然后计算贡献,如果以sa的顺序新增那么第i个就会产生n-sa[k]+1-h[k](n-sa[k]+1为总方案,h为不合法的方案),累计即可。 1 #include<bits/stdc++.h> 2 using namespac 阅读全文
摘要:
考虑定义以下dp数组:1.g1[i][j]表示第i行从中间出发向左取j瓶牛奶最少要多久2.g2[i][j]表示第i行从中间出发向右取j瓶牛奶最少要多久3.g3[i][j]表示在g1[i][j]的基础上回到中间最少要多久4.g4[i][j]表示在g2[i][j]的基础上回到中间最少要多久5.f1[i] 阅读全文
摘要:
最大团=反图的最大独立集,而反图又恰好是一张二分图,根据二分图的最大独立集=n-最大匹配就可以做了。 1 #include<cstdio> 2 #include<cstring> 3 #define N 405 4 struct ji{ 5 int nex,to; 6 }edge[N*N]; 7 i 阅读全文