传送门 思维题. 考虑维护两个数列的前缀和a1,a2,a3,...,ana_1,a_2,a_3,...,a_na1​,a2​,a3​,...,an​和b1,b2,b3,...,bnb_1,b_2,b_3,...,b_nb1​,b2​,b3​,...,bn​.不妨设an≤bna_n\le b_nan​≤bn​. 由于两个数列每个数都在1~n之间,所以说对于每一个aia_iai​总能找到一个比aia_iai​小且最接近的bjb_jbj​,使得0≤ai−bj≤n−10\le a_i-b_j\le n-…
题目链接:http://codeforces.com/contest/618/problem/F 题目: 题目大意: 有两个大小为 N 的可重集 A, B, 每个元素都在 1 到 N 之间. 分别找出 A 和 B 的一个子集, 使得这两个子集元素之和相等. 分别输出集合A和集合B的子集的个数以及子集中元素在原集合中的位置 N ≤ $10^6$ 题解: 首先我们证明一个结论,存在一组方案,满足两个子集在A中和在B中都是连续的一段 把两个集合看成两个数组,分别计算出前缀和sa,sb 对于每个i(0<…
传送门 简单概率dp. 显然每次转移的式子可以用一个矩阵表示出来: 这个是循环矩阵. 因此只用维护第一行快速幂一波就行了. 代码: #include<bits/stdc++.h> #define N 1005 using namespace std; int n,m,K,a[N]; double b[N]; struct Matrix{double val[N];}ans,tmp; inline Matrix operator*(Matrix a,Matrix b){ Matrix c; me…
传送门 概率dp经典题目. 直接f[i][j][k]f[i][j][k]f[i][j][k]表示当前是第i次挑战,已经胜利了j次,目前的背包剩余空间是k. 然后用前面的转移后面的就行了. 注意第三维可能是负数,需要用一些技巧转化一下(比如把整个数组的下标向右平移) 代码: #include<bits/stdc++.h> #define N 205 using namespace std; int n,l,K,a[N],tmp; double p[N],f[2][205][605],ans; i…
传送门 一道有意思的期望dp. 题意是给出一棵树,每个点最开始都有一个gg的概率,有m次修改,每次修改会把某个点gg的概率更换掉,让你求出每次修改之后整个树被分成的连通块的数量的期望(gg掉的点不算). %%%%dzyo神仙. 考虑每个点对答案的贡献. 一个点对答案有贡献当且仅当它的父亲gg且它自己没有gg. 于是这样所有加起来就是一次询问的答案. 接着考虑如何解决多次询问. 每次修改一个点的点权,只会影响它的儿子与父亲对答案的贡献. 因此我们直接维护一个sum数组表示所有儿子不gg的期望之和.…
传送门 好题啊. 我只会写l,rl,rl,r都很小的情况(然而题上并没有这种数据范围). 但这个dp转移式子可以借鉴. 我们用f[i][j][k]f[i][j][k]f[i][j][k]表示当前在第i位,模7余j,当前位是k. 显然有f[i+1][([j∗10+l)f[i+1][([j*10+l)f[i+1][([j∗10+l)%7][l]+=f[i][j][k]7][l]+=f[i][j][k]7][l]+=f[i][j][k]. 但是i上限1e91e91e9,直接做会凉. 于是我们构造矩阵来…
传送门 好题啊. 首先找到最小的一个非零系数记做a1a_1a1​,然后如果WWW modmodmod a1=W′a_1=W'a1​=W′ modmodmod a1a_1a1​,且WWW是方程的一个可行解,那么显然W′W'W′也是一个可行解. 自然会想到我们用完全背包的思想对每一个余数求出要达到这个余数的最小可行解,这样整个范围中到达这个余数的可行解个数就可以统计出来了. 因此我们把所有BBB模a1a_1a1​的余数看做点,那么aaa数列就能够被当做边权,在建出的图上面跑最短路就行了. 代码: #…
传送门 简单dp. 根据题目的描述. 如果数列bn{b_n}bn​合法. 那么有:bi−1b_{i-1}bi−1​&bi!=0b_i!=0bi​!=0,因此我们用f[i]f[i]f[i]表示数列b最后一位第i个二进制位为1的时候b数列的最长长度. 然后简单转移一下就行了. #include<bits/stdc++.h> #define N 100005 using namespace std; inline int read(){ int ans=0; char ch=getchar(…
传送门 一道比较综合的数位dp. 维护三个值:[L,R][L,R][L,R] 区间中与7无关的数的数量,与7无关的数之和,与7无关的数的的平方和. 然后可以用第一个值推第二个,第一个和第二个值推第三个. 代码: #include<bits/stdc++.h> #define ll long long #define mod 1000000007 using namespace std; ll L,R,mul[30]; int t,len,num[20]; struct DP{ll c,s1,s…
描述 一些学校连接在一个计算机网络上.学校之间存在软件支援协议.每个学校都有它应支援的学校名单(学校 a 支援学校 b ,并不表示学校 b 一定支援学校 a ).当某校获得一个新软件时,无论是直接得到还是网络得到,该校都应立即将这个软件通过网络传送给它应支援的学校.因此,一个新软件若想让所有连接在网络上的学校都能使用,只需将其提供给一些学校即可. 任务 请编一个程序,根据学校间支援协议(各个学校的支援名单),计算最少需要将一个新软件直接提供给多少个学校,才能使软件通过网络被传送到所有学校: 如果…