10 2019 档案
摘要:容易发现操作任意次并不会改变每一个点的概率(因为每一个点加d的概率相同,期望与原数成比例),然后直接输出即可(要用高精度) 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 20005 4 int n,m,k,x,s,a[N],
阅读全文
摘要:以i为开头的最长上升子序列,那么就是反过来以i为结尾的最长下降子序列,预处理出来后,不断向后找到下一个数即可 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 10005 4 int n,m,x,a[N],b[N],f[N];
阅读全文
摘要:用b[i]表示第i个人给第i+1个人(b[n]表示给1,可以为负)的糖果数量,显然有$ai+b_{i-1}-bi=\sum_{i=1}^{n}ai/n$很容易构造出某一组bi(例如确定b1=0),那么我们可以让所有bi加上某个值,然后最小化$\sum_{i=1}^{n}|bi|$当bi中正数个数多于
阅读全文
摘要:第一个问题可以用贪心+二分解决第二个问题用f[i][j]表示i次分割后分割到j且满足条件的方案数,$f[i][j]=\sum_{k<j且sum[j]-sum[k]<=ans}f[i-1][k]$优化时间:前缀和优化,二分要先预处理出来(也可以用优先队列)优化空间:发现f并没有什么用处,只需要记录前缀
阅读全文
摘要:先预处理出没有上限的方案数,然后容斥,然后将所有东西的范围都变为[0,+oo),即可用预处理出的dp数组计算 1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,s,a[11],b[11]; 4 long long ans,f[10000
阅读全文
摘要:设$x^2+y^2=n^2$,令$d=gcd(x,y)$,那么$n'^2=x'^2+y'^2$,即$y'=\sqrt{n'^2-x'^2}$由于$gcd(n'+x',n'-x')=1$,因此$n'+x'$和$n'-x'$都应该是完全平方数由于d是n的约数,所以枚举d,令$n'-x'=a^2$,暴力枚
阅读全文
摘要:容易证明,最终方案一定是某一个排列无限循环,那么就要满足$\sum ai<=max(bi+ai)$,对所有数按照ai+bi排序后,枚举最大值,用权值线段树维护之前的ai最少要选几个 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define
阅读全文
摘要:将仇恨关系连边后,这张图实际上就是一张基环树森林,对于一颗树显然可以十分容易的dp,那么先对于基环树上的某一棵生成树dp两次,分别令那条非树边的两端中的某一个点不能选,另一个点随意,两次取max即答案 1 #include<bits/stdc++.h> 2 using namespace std;
阅读全文
摘要:dp,用f[i][j][x][y]表示i个男孩,j个女孩,以i+j为结尾的子序列男-女最多为x,女-男最多为y的合法方案数,转移到f[i+1][j][x+1][max(y-1,0)]和f[i][j+1][max(x-1,0)][y+1](注意要保证x和y不超过k) 1 #include<bits/s
阅读全文
摘要:先将连续的一段相同的点连起来,然后考虑对于一段区间,分两种情况:1.首尾两点再同时消掉,必然要先将去掉首尾的一段消掉后再消2.首尾两点再不同时刻消掉,那么必然存在一个断点k,使得k左右无关(题目中的错误指的是某一段和相同颜色的另一段因消除而合并时暂时不消掉,这在祖玛游戏中是不被允许的,因此并无错误)
阅读全文
摘要:将所有字符串建一个ac自动机,用f[i]表示随机字符串匹配到第i个字符的概率,可以转移到某些字符,如果这个点是末尾那么他只能转移到自己且概率为1,高斯消元即可(另外还有一个有趣的做法,因为精度要求不高,可以直接对这个矩阵自乘50次得到的就是结果) 1 #include<bits/stdc++.h>
阅读全文
摘要:记f(n)表示n的约数和,先不考虑a的限制,那么即求$\sum_{i=1}^{n}\sum_{j=1}^{m}f(gcd(i,j))$枚举$d=gcd(i,j)$,即$\sum_{d=1}^{n}f(d)\sum_{g|d}(n/gd)(m/gd)\mu(g)$(后面就是指公约数为d的数对个数)令$
阅读全文
摘要:1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 10000005 4 int t,n,m,vis[N],p[N],f[N]; 5 long long ans; 6 int main(){ 7 f[1]=0; 8 for(int
阅读全文
摘要:建立方程后直接高斯消元,再把0的区间找出来计算,就可以过(因为实际上这样的复杂度是5次的,且常数小)(当然这样的复杂度看上去并不太好,考虑优化)可以发现最后一行的概率都可以用上一行来表示,那么代入上一行的方程后,发现又可以再次代入,最后就求出了第一行 1 #include<bits/stdc++.h
阅读全文
摘要:不妨假设ai<bi(不满足交换),线段树维护区间左端点取ai/bi,右端点最小是多少,修改时相当于两次单点修改(注意修改是永久的) 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 200005 4 #define oo 0x3
阅读全文
摘要:直接求出任意两点的距离后记忆化搜索,用f[i][j]表示聪聪在i,可可在j的期望步数,由于i和j的最短路单调递减,所以搜不到环 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 1005 4 vector<int>v[N]; 5
阅读全文
摘要:可以看成一张二分图,判断左半部分是否存在完美匹配根据hall定理,当且仅当左半部分每一个子集所连向的点数量超过了这个子集的大小都判定复杂度肯定爆炸,可以贪心,一定选择的是一个区间,即对于任意区间[l,r],都要满足$\sum_{i=l}^{r}ai\le (r-l+1+d)k$(ai表示i号鞋子的人
阅读全文
摘要:先将所有数加上Ri,即变为区间[0,2Ri],考虑容斥,将区间容斥为[0,+oo)-[2Ri,+oo),然后对[2Ri,+oo)令$bi=ai-2Ri$,相当于范围都是[0,+oo)问题转化为求n个正无穷范围的数和不超过b的方案数,大胆猜测后发现就是$b^{n}/n!$,暴力累计即可 1 #incl
阅读全文
摘要:记p(i,j)表示第i次随机时,用多少个数对应到第j个事件,特别的,p(i,0)表示转移到下一次随机数的概率,那么即要求$aj/bj=\sum_{i=1}^{inf}p(i,j)/R^{i}$,容易发现这就是$aj/bj$的R进制表示,可以求出其中的某一组解然后设f(i)表示第i次随机,有多少个数转
阅读全文
摘要:考虑分别求出RG和GB的最小生成树,然后剩下的边中肯定选择较小的边加入这两颗生成树 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 105 4 struct ji{ 5 int x,y,z; 6 char s[11]; 7 }
阅读全文
摘要:将两棵树分别按照深度分块,即每$\sqrt{n}$深度分为一块对于两棵树任意两个块的根对,统计其中公共的节点并计算出答案(用按秩合并并查集),复杂度为$o(n\sqrt{n}logn)$(其实这玩意是可以被卡掉的,因为这种分块无法保证块的大小和数量) 1 #include<bits/stdc++.h
阅读全文
摘要:考虑对一个集合求莫比乌斯反演的过程,最终答案即$\sum\limits_{d|ai}\mu(d)\cdot calc(d)$(calc(d)表示i子树中d倍数的个数)dfs时维护当前遍历到的点中i倍数的个数,对i搜之前和i搜完后差分一下就可以得到i子树的信息,用上述式子计算即可 1 #include
阅读全文
摘要:考虑每一条非树边都连接了祖先和儿子,类似于序列上的问题,从底往上算,当发现如果走到某个环的祖先,且这个环中还没有被选到,那么就将最浅的那条边贪心选择即可具体实现可以使用bitset维护当前子树的询问,如果这条边选了,那么bitset清空,否则和父亲合并 1 #include<bits/stdc++.
阅读全文
摘要:对于权值最大的点,他一定会在父亲选完后立刻选,所以不断将其与父亲合并,直到只剩一个点就是答案由于n比较少,可以直接暴力,如果n较大取最大值可以用堆,修改父亲可以用并查集 1 #include<cstdio> 2 #define N 1005 3 int n,r,x,y,ans,a[N],f[N],s
阅读全文
摘要:有两个贪心:1.自底向上dfs,能删就删,这样显然是正确的,因为它最多只会造成它父亲不能删除;2.对于一个节点,优先删除其代价($c[i]+son[i]$)最大的i删除,一定最优,证明略 1 #include<bits/stdc++.h> 2 using namespace std; 3 #defi
阅读全文
摘要:考虑二分枚举答案,变成01的一个序列,用线段树来维护排序即可 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 100005 4 #define L (k<<1) 5 #define R (L+1) 6 #define mid
阅读全文
摘要:建立点分树(以下除距离都指在点分树上的,距离可以每一次倍增计算lca)对于每一个点,维护子树内所有点到这个点的距离的线段树和子树内所有点到这个点父亲的距离的的线段树,然后对于查询和修改暴力修改或询问每一个祖先即可(点分数树高logn) 1 #include<bits/stdc++.h> 2 usin
阅读全文
摘要:倍增,对于每一个点计算他走到$2^i$次祖先所需要的攻击力以及最终会变成什么(一个一次函数),简单处理即可(然而这样是错的,因为他只保证了骑士的攻击力可以存,并没有保证这个一次函数的系数可以存)(其实还可以用科学记数法即pair<long double,int>来存即可,只要注意精度&常数)正解是模
阅读全文
摘要:可以发现分割的顺序并不会影响答案,也就是一个划分的问题dp,用f[i][j]表示前i个数划分为j段的答案,那么方程是$f[i][j]=max(f[k][j-1]+(S[i]-S[k])*(S[n]-S[i])$,滚动+斜率优化即可 1 #include<bits/stdc++.h> 2 using
阅读全文
摘要:对网格图黑白染色,在黑色格中填不同的质数,白色格中填相邻黑色格的lcm+1,但这样会超过1e15的上限将网格图划分为两类对角线,每一条对角线选一个质数,然后每一个点就是两条对角线的质数相乘,而白格的值就仅为四个较小质数的乘积+1(注意不能让两个大质数配到一起) 1 #include<bits/std
阅读全文
摘要:先按照d从小到大排序,遍历所有建筑i,如果能修,显然要去修的考虑不能修,显然选择让之前所需时间最多的那个建筑不修(如果就是自己那就放弃),用堆来维护 1 #include<bits/stdc++.h> 2 using namespace std; 3 struct ji{ 4 int t,d; 5
阅读全文
摘要:二分答案,考虑答案是否会大于等于这个mid,显然所有数值分为两类:大于等于mid和小于mid将n个数转化为01串,如果0和1不相邻,那么答案就是第一个数/最后一个数(一定会相同),考虑有连续两个0/1否则连续的两个数一定会上升到某一个高度并变为一个数,因此只需要找到最高的一层全部变成0/1时,也就是
阅读全文
摘要:有一个结论:两个区间的最长路的端点一定是这两个区间中的最长路端点(4选2),所以可以用线段树来维护区间最长路的两个端点,然后最终合并即可 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 100005 4 #define L (
阅读全文
摘要:将s所有长度为d/2的子串放进ac自动机中,直接匹配就可以判定半现串了再对其做一个差分,询问一个前缀的半现串个数,在ac自动机上数位dp,f[i][j][0/1]表示走了i步(i位的字符串),走到节点j,是否达到上限的方案数对于ac自动机上的结束节点,直接重置并累计答案即可 1 #include<b
阅读全文
摘要:首先可以发现对于两条链来说,显然是对两边都排好序,然后大的配大的,小的配小的(正确性比较显然),最后再加入根(根只能单独选)这个结果其实也可以理解为将所有max构成一条新的链,求出因此,对于每一个结点计算出答案,然后与别的点合并得到父亲,用启发式合并+set时间复杂度为两个log。 1 #inclu
阅读全文
摘要:分治,维护一个dp数组,当递归到区间[l,r]时,需要保证这个dp数组维护的是除去[l,r]以外的dp数组维护其实很简单,就是递归左区间是先将右区间加入,然后再将左区间加入(要先复原)然后递归右区间即可 1 #include<bits/stdc++.h> 2 using namespace std;
阅读全文
摘要:先考虑一个联通块,可以发现这个联通快内不会存在两个偶数的点证明:如果存在,那么这两个点的某一条路径上的边全部反过来,可以使答案+2,即答案为点数或点数-1同时,发现答案的奇数点数一定与边数同奇偶,那么答案就被确定了,具体实现可以使用并查集 1 #include<bits/stdc++.h> 2 us
阅读全文
摘要:(以下用$Sa=\sum_{j=1}^{i}xi\cdot ai$,Sb和Sc同理)令f[i][x]表示前i个数,$Sa\le x\le Sb$时最小的Sc考虑第i个数是否选择,可以得到递推式$f[i][x]=min(f[i-1][x],min(f[i-1][x-j])+ci)$(j满足$ai\le
阅读全文
摘要:先可以将所有出度为0的节点连向一个点,然后问题变为求到这个点的必经之点这其实是一道模板题,因为有一个东西叫做支配树容易发现一个点的必经之点都是一条链,其实可以把这条链上最浅的点作为这个点的父亲,那么一个点的所有必经之点显然就是他到根的路径上的点具体来说,这个点的父亲就是他所有联通的点的lca(不能叫
阅读全文