摘要:用主席树写起来跑的快一点,而且也很傻比,二分答案,即二分那个半径就行 主席树求的是区间<=k的个数 #include<bits/stdc++.h> using namespace std; #define maxn 1000005 int a[maxn],n,m; struct Node{int l
阅读全文
摘要:/* 给定一组n维向量 A=(a1/m,a2/m,a3/m ... an/m), 求另一个n维向量 P=(p1,p2,p3...pn),满足sum{pi}=1,使得ans=sum{(ai/m-pi)^2}最大化 并求出这个ans 首先将ai放大m倍 A=(a1,a2,a3...an) 同理 P=(p1,p2,p3...pn),sum{pi}=m 将ai按照降序排序,可以推出大的数减掉x一定比小...
阅读全文
摘要:/* 给定数组a[],求有多少集合的异或值为0,将这些集合的大小之和求出来 对于每个数来说,如果除去这个数后数组里做出的线性基和这个数线性相关,那么这个数贡献就是2^(n-1-线性基的大小) 反之这个数和线性基线性无关,即数组里凑不出这个数来和其异或等于0,所以贡献就是0 由于做n次线性基很麻烦,所以简化问题,只需要先做出一个基,将数分成在基内和基外即可 首先做出一个线性基base,设其大...
阅读全文
摘要:cf1100F是静态区间查询最大值,有离线的解法,我感觉线段树或者莫队应该都能过 更优秀的解法可以在线并支持修改,可以解决hdu6579,即依次插入每个数,pos[i][j]表示在插第i个数时第j个基出现的最靠右的位置,然后p[i][j]来表示插第i个数时第j个基的值 考虑普通的线性基插入值x的过程
阅读全文
摘要:/* 首先想到二分答案,难点在于如何判断是否有K段,每段和=pre[i]-mid的j,那直接用线段树维护代表pre[j]的dp_max[j]即可,然后就可以进行查询 要注意处理边界问题(pre[0]=0的情况) */ #include using namespace std; #define maxn 200005 #define ll long long #define INF 0x3f3f...
阅读全文
摘要:具体理解看博客就可以了 下面是一些数组的定义,这是必须要记住的
阅读全文
摘要:比赛的时候没看到模数,用java大数在写,最后看到的时候已经慌了。。 把贡献算清楚就可以 下面是贡献的推导 有五位数 abcde * 10个 有两位数 fg * 3 个 那么这两种数组成的情况就是 abcdfeg 或 abcfdge,现在只考虑五位数在前,两位数在后的情况, 五位数的情况是abcd_
阅读全文
摘要:本题前面的操作别的博客里都有。难点在于颜色ci的贡献,如何一次dfs求出答案 先来考虑如何在一次dfs中单独对颜色i进行计算 用遍历dfs序的方式,在深搜过程中,碰到带有颜色 i 的点 u,u每个颜色不为i的子节点v都会贡献一个联通块, v的贡献的联通块大小是size[v]-sum{v中层次最高的以
阅读全文
摘要:虚树的核心就是把关键点和关键点的lca重新生成一棵树,然后在这棵树上进行dp https://www.cnblogs.com/zwfymqz/p/9175152.html 写的很好的博客 建立虚树的核心代码 本题的ac代码 #include<bits/stdc++.h> using namespac
阅读全文
摘要:/* 引理:[0,n-1]的排列,i向a[i]连边,那么每个数必定在一个环中 所以数组a可以分割成一些环,数组b也可以分割成一些环 先讨论a的一个环 a[a1]=a2 a[a2]=a3 a[a3]=a4 a[a4]=a5 a[a5]=a6 a[a6]=a1 这个环长度为6 那么套到函数 f[i]=b[ f[a[i] ]中 f[a1]=b[f[a2]] f[a2]=b[f[a...
阅读全文
摘要:#include #include using namespace std; const int MAXN = 1e5+7; const long long mod = 1e9+7; int n; int maxj; struct node { int id; int num[MAXN]={0}; bool operator = 0; --j) ...
阅读全文
摘要:/*首先考虑如何计算一个点的可能凑出的值,这就是一个01可行性背包问题那么再拓展到一段区间[1..n]的点上,每个query都可以看做是一段区间上的点[l,r]加上一个体积为x的物品,转换到01背包上就是进行一次更新那么用线段树来维护每个query的区间更新 每个位置(区间)维护一个bitset,每次加入a都进行一次01背包 用线段树来维护区间的bitset,表示一段区间能组成的值 但是没法用l...
阅读全文
摘要:把所有点离散化,虚构一根扫描线从上往下扫,每行的点从左往右算贡献,开一个树状数组维护每个离散化后的x坐标是否已经有点 扫描到一个点时,先把这个点更新到树状数组里,每个点的贡献是它左边的所有点数*到它相邻右边点之间的所有点数
阅读全文
摘要:因为是模3,所以把原矩阵拆成两个01矩阵,然后按分配律拆开分别进行矩阵乘法,行列用bitset来存进行优化即可 注意 int bitset<int>::count() 函数可以统计bitset里有多少1 int bitset<int>::any() 函数可以统计bitset里是否有1
阅读全文
摘要:首先就是求联通块,每个联通块里记录两个部分的元素个数 目标是使一边的体积接近n/2 那么每个联通块作为一组,进行分组背包,dp[i]表示体积i是否可以被凑出来,可行性背包是可以用bitset优化的 最后找最接近n/2的体积即可
阅读全文
摘要:bitset的经典优化,即把可行性01数组的转移代价降低 bitset的适用情况,当内层状态只和外层状态的上一个状态相关,并且内层状态的相关距离是一个固定的数,可用bitset,换言之,能用滚动数组是能用bitset优化的前提
阅读全文
摘要:口胡一种别的解法: 三重退背包,g1[j]k]表示不选x的选了j件物品,体积为k的方案数,g[0][0] = 1 , g1[j][k]=dp[j][k]-g1[j-1][k-a[x]] 然后按这样再退三层,最后看g3[10][87]的方案数是否非0即可,这样复杂度是O(50*50*50*10*87)
阅读全文
摘要:/* 要求把a数组分成两个集合,两个集合人数最多差1,并且元素之和的差尽可能小 那只要把所有可行的列出来即可 01二维背包,即体积是个二维数据,那么我们的背包状态也应该设为二维 dp[j][k]设为 有j个人,体积为k的状态是否可行 第一维上限是人数的一般,第二维上限是元素总和的一半 */ #include #include #include using namespace std;...
阅读全文
摘要:我们首先得到: 暴力打开这个箱子,能够开那些箱子。这个可以用bitset来进行状态压缩。 用闭包传递来解决这一步 然后,对于每个箱子,我们考虑有多少种方法,使:暴力打开某些箱子,同时能打开这个箱子。 暴力开这个箱子的期望就是方案数的倒数。然后我们对开每个箱子的期望求和就是最终的打开所有箱子暴力开箱子
阅读全文
摘要:/* 二分答案,判mid是否合法 如何判断:如果是在直线上,那么遍历匹配即可 现在在环上,即既可以向前匹配也可以向后匹配,那么将环拆开,扩展成三倍 显然a和b的匹配边是不可能交叉的,因为交叉必定没有不交叉优 hall定理:二分图两个点集A,B,连续一段A的点对应连续一段B的点的 充要条件是 这些点对的匹配边之间不交叉 重要推论:二部图G中的两部分顶点组成的集合分别为X,Y, 若|X|=|...
阅读全文
摘要:感觉自己的解法很复杂,写了一大堆代码 但核心是从小到大枚举每个元素的值,然后把<=当前元素的值进行合并,由于这个过程是单调的,所以可以直接将新的元素合并到旧的并查集里去 维护并查集的同时维护每个集合的大小size,将size放在multiset 里然后判断每个块的大小是否相同,如果相同则更新答案
阅读全文
摘要:非常好的题!和spoj 的 Mobile Service有点相似,用记忆化搜索很容易解决 看了网上的题解,也是减掉一维,刚好可以开下数组 https://blog.lucien.ink/archives/224/ 此外是滚动数组的版本(没有降维复杂度比较高)
阅读全文
摘要:推出一个很神奇的结论就可以进行dp了 这个结论不光可以用在异或操作上,还可以用在任意操作里
阅读全文
摘要:/* dp[i]=0|1 表示前i是否可以被成功分组, dp[i+1]能够变成1的三个条件 1:j∈[0,i-k]里存在dp[j]=1 2:dp[j]=1 3:a[i+1]-a[j+1] using namespace std; #define maxn 5000005 int d,dp[maxn],a[maxn],n,k; int bit[maxn]; void upd...
阅读全文
摘要:分两种情况进行讨论,要注意判条件时会有爆ll
阅读全文
摘要:很好的题,想了半天,官方题解的解法更好 这种异或问题的包含性在北邮的校赛里就出现过,需要认真学习一下
阅读全文
摘要:退背包就是限制某一件物品不可取的方案数 先做出无限制的方案数,然后对于当前不可取的物品,dp2[j]表示不取改物品情况下,取得体积为j的方案数 有状态方程 dp2[j]=dp1[j]-dp2[j-w[i]] 即无限制下取到体积j的方案数 - 有限制下取得体积j-w[i]的方案数(还有w[i]的体积用
阅读全文
摘要:学了一种新套路,倒序打表函数的逆元可以直接线性完成
阅读全文
摘要:#include using namespace std; #define ll long long #define mod 1000000007 #define maxn 5000005 ll n,m,K; ll Pow(ll a,ll b){ ll res=1; while(b){ if(b%2)res=res*a%mod; b>>=1;a=...
阅读全文
摘要:这题首先要会线性筛约数个数,并求出前缀和 bool vis[maxn]; int mm,mu[maxn],prime[maxn],num[maxn],sum[maxn],d[maxn],sum1[maxn]; void init(){ mu[1]=1;num[1]=1; for(int i=2;i<
阅读全文
摘要:首先想到用二分来判断 不是平方数的倍数,即没有次数>=2的质因子显然用容斥原理,即所有答案-1个质因子的平方的所有倍数+2个质因子的所有平方倍...等价于对于每个数,如果它有奇数个质因子,那么其贡献系数是-1,反之则是1, 如果自己本身有平方因子(比如2*2*3),那么其贡献系数是0,因为已经被前面
阅读全文
摘要:学了一种爆搜版+剪枝的容斥方法,即类似数位dp时按位进行容斥,同时需要在搜索过程中进行剪枝
阅读全文
摘要:第二次做这题,求前缀和的时候还是卡住了 fg函数的反演是可以直接用莫比乌斯基本代换式来代换的
阅读全文
摘要:/* 求 n! 在base进制下的位数 取对数,用换底公式,预处理对数前缀和 b^x = n! x = log_b(n!) = log_10(n!)/log_10(b) 对x向上取整即可 */ #include using namespace std; #define maxn 1000005 double sum[maxn]; void init(){ for(int i=...
阅读全文
摘要:#include using namespace std; #define ll long long #define maxn 200 int primes[maxn],m; bool vis[maxn]; void init(){ for(int i=2;i=maxn)break; vis[i*primes[j]]=1; if(i%p...
阅读全文
摘要:#include using namespace std; #define ll long long #define maxn 1000005 bool vis[maxn]; int m,primes[maxn]; void init(){ for(int i=2;i=maxn)break; vis[primes[j]*i]=1; if(...
阅读全文
摘要:要用 System.gc() 清理内存 类必须命名成Main,一些大整数的操作
阅读全文
摘要:/* 给定n个盒子,第i个盒子有ai朵花,现在从中选取m朵花,问选取方案数 用容斥定理解决 m=x1+x2+..+xn C(m+n-1,n-1)+sum{ (-1)^p * C(m+n-1-(1+n1)-(1+np),n-1) } */ #include using namespace std; #define ll long long #define mod 1000000007...
阅读全文
摘要:/* 树上莫比乌斯反演 求树上 满足 d|gcd(au,av) gcd(au,av)的对数f(d) 如何求: 建立200000层新图,即对于每个数建立一个新图 在加边时,给gcd(au,av)的约数层的图的uv加边 f[i]表示第i层的满足条件 i | gcd(a[u],a[v]) 的对数,那么求一遍并查集,在合并过程中更新f[i]即可, 同时要注...
阅读全文
摘要:/* 结论1:有解的充要条件是所有点权之和为0 结论2:删掉环上的一条边,只要将这个环上的其余边都减去这条边的边权,那么这个图仍是等价的 从原图网络中构造出一棵带权值的树即可,其他边权都设置为0 通过dfs建立一棵搜索树 要注意处理边的方向 */ #include using namespace std; #define maxn 200005 struct Edge{int to,nxt,w...
阅读全文
摘要:假设以u为根时结果是tot,现在转换到了以u的儿子v为根,那么结果变成了tot-size[v]+(sizetot-size[v]) 根据这个转移方程,先求出以1为根的tot,然后dfs一次转移即可
阅读全文
摘要:/* 排除掉所有不可能的情况,剩下的就是可行的 1.数的数量不相同 2.对任意一个区间进行排序,等价于可以交换任意逆序对, 那么从1到n扫描b数组,判断是否可以将a数组中等于b[i]的值所在的位置j交换到位置i,等价于判断区间a[i,j]是否存在 #include using namespace std; #define maxn 300005 #define inf 0x3f3f3f3...
阅读全文