摘要:【题目描述】 给定一个n*m的矩阵,矩阵的某些位置有一个颜色(可以没有颜色,即为0),现在你可以将矩阵的某一行或者某一列染成同一种颜色,问最少用多少步能达到目标矩阵的染色方案,输出最少步数和方案。 【数据范围】 n,m#include #define maxn 60#define inf (~0U>>1)using namespace std;struct rec { int sum; int topo[maxnn) printf("C %d",ans.topo[i]-n); else printf("R %d",ans.topo[i]);
阅读全文
摘要:首先我们可以求出来所有食物的母函数: 汉堡:f(x)=1/(1-x^2)。 可乐:f(x)=1+x. 鸡腿:f(x)=1+x+x^2. 蜜桃多:f(x)=x/(1-x^2). 鸡块:f(x)=1/(1-x^4). 包子:f(x)=1+x+x^2+x^3. 土豆片炒肉:f(x)=1+x. 面包:f(x)=1/(1-x^3). 然后我们可以将他们全乘起来,得到f(x)=x/(1-x)^4.然后根据泰勒展开1/(1-x)^n=1+C(n,1)x^1+C(n+1,2)x^2+C(n+2,3)x^3+...+C(n+k-1,k)x^k+...。 可以得到第n项的系数为c(n+2,...
阅读全文
摘要:这道题有些类似卡特兰数的其中一种证明,总方案数是c(n+m,n),点(m,n)对应y=x-1对称点为(n+1,m-1),所以答案为c(n+m,n)-c(n+m,n+1)。 反思:开始坐标轴画错了,结果得到的是c(n+m,n-1),然后就错了= =。 /**************************************************************Problem: 1856User: BLADEVILLanguage: C++Result: AcceptedTime:5220 msMemory:804 kb****************************...
阅读全文
摘要:首先我们对于一颗树,要选取最多的节点使得代价和不超过m,那么我们可以对于每一个节点维护一个平衡树,平衡树维护代价以及代价的和,那么我们可以在logn的时间内求出这个子树最多选取的节点数,然后对于一个节点的平衡树我们可以由他的子节点启发式合并而来,时间复杂度nlog^2n。 这道题还可以用左偏树来解决,左偏树为一种可合并堆,合并,删除,插入都在logn内完成,那么这道题的时间复杂度还可以nlogn。 反思:我写的是左偏树的,手残把value打成cost了= =,查了半天。 /*********************************************************...
阅读全文
摘要:【题目描述】 一个长为n的序列,每个元素有一个a[i],b[i],a[i]为0||1,每个点和他相邻的两个点分别有两条边,权值为cost1[i],cost2[i],对于每个区间l,r,我们可以给每一个数一个c[i]值,c[i]=0||1,使得Σ(b[j]*(a[j]^c[j]))+cost1[j]*(c[j]^c[j+1])+cost2[j]*(c[j]^c[j+2]),j,j+1,j+2在[l,r]内时累加,现在有m次操作: M x:将x位置的a[i]^=1; Q l r:询问区间l,r的答案。 首先假设询问的只是一个区间,那么我们可以比较容易的用dp来求解w...
阅读全文
摘要:【题目描述】给定一颗树,每个点有各自的权值,任意选取两个点,要求算出这两个点路径上所有点的and,or,xor的期望值。 【数据范围】n#include #define maxn 100010#define LL long long#pragma comment(linker,"/STACK:102400000,102400000")using namespace std;LL n,l;LL pre[maxn<<1],other[maxn<<1],last[maxn],key[maxn],color[maxn],sum[maxn],size[maxn
阅读全文
摘要:首先我们可以比较容易的在n的时间内算出来开始的答案,我们维护一些链表,分别表示不同的颜色,那么我们在计算答案的时候,只需要扫一遍所有的链表,判断链表相邻两项是否在序列中相邻,不相邻的话肯定在这其中的一个唯一有一个断的点,也就是分成了两个不同的颜色段,直接累加答案就好了。 然后我们对于每个询问,将颜色x换成颜色y,那么我们找到这两种颜色的链表,将小的链表连接到大的链表之后,同时统计由于合并两个链表而对答案造成的影响。这样直接合并是不行的,因为我们由于链表的长度而改变了合并的顺序,所以我们可以记录一个father[x],代表这个点的颜色,这样我们就可以合并了。 /*************...
阅读全文
摘要:首先对于一个连通块中,询问我们可以直接用平衡树来求出排名,那么我们可以用并查集来维护各个块中的连通情况,对于合并两个平衡树,我们可以暴力的将size小的平衡树中的所有节点删掉,然后加入大的平衡树中,因为每个点只可能被删除插入logn次,所以时间复杂度为nlog^2n。 /**************************************************************Problem: 2733User: BLADEVILLanguage: C++Result: AcceptedTime:2112 msMemory:64868 kb****************...
阅读全文
摘要:因为最多有8个'X',所以我们可以用w[i][s]来表示现在我们填了前i个数,填的X的为S,因为每次新加进来的数都不影响前面的最小值,所以我们可以随便添加,这样就有了剩下所有位置的方案,每次都这样转移。 但是这样会造成不是规定的地方出现局部最小值的情况,对于这样的情况,我们只需要枚举所有可能成为局部最小值的不合法状态来做容斥就可以了。 反思:这道题的容斥开始写错了,本来应该是判奇偶来判断正负,写成了全是负的,还是A了,应该是后面的容斥没有合法方案所以符号无所谓的关系,真是rp++。/************************************************
阅读全文
摘要:首先如果不考虑数据范围的话,因为每一层都是等效的,所以我们可以用w[i][j][k]来表示在某一层的j位置,称作i次电梯到k位置,最多上升多少层,那么我们可以比较容易的写出转移,因为m十分大,i可能与m同阶,所以我们不能直接枚举i,这样我们考虑二进制的思想,w[2^p][j][k]表示用了2^p次电梯,最多上升的层数,那么这样我们可以直接由w[2^p-1][j][mid]和w[2^p-1][mid][k]转移过来,但是这样求出来的是我们最少用2^p次可以到达m层,最后的答案可能会比这个小,那么我们可以逐位的判断答案,是否可以通过减少某一位的1仍能达到m层,那样我们这个1就可以去掉,也就是不..
阅读全文
摘要:【题目描述】给定2-3颗树,每个边的边权为1,解决以下独立的问题。 现在通过连接若干遍使得图为连通图,并且Σdis(x,y)最大,x,y只算一次。 每个点为黑点或者白点,现在需要删除一些边,使得图中的黑点度数为奇数,白点为偶数,要求删除的边最多。 【数据范围】 100% n#include #include #define maxn 100010#define LL long longusing namespace std;LL n,m,l;LL a[maxn],pre[maxnmax_a[aa]) aa=other[p]; if (max_b[other[p]...
阅读全文
摘要:【题目描述】一个2*i的矩阵,一共有m种颜色,相邻两个格子颜色不能相同,m种颜色不必都用上,f[i]表示这个答案,求Σf[i]*(2*i)^m (1#define LL long long#define maxp 1010#define maxm 1010using namespace std;int n,m,p,a;int mo[maxp],next[maxp],w[maxm],c[maxm][maxm];int flag[maxp][maxp],f[maxp*maxp],g[maxp*maxp];int mi(int a,int k) { int ans=1; while ...
阅读全文
摘要:对于burnside引理需要枚举染色,这道题属于burnside的一种简单求解的方法,就是polya,我们可以使每一种置换中的循环节中的元素的颜色都相同,那么这样的话就可以直接DP了,我们可以将m个置换单独考虑,处理出当前置换中各个循环节,那么用w[aa][bb][cc]表示在使用了aa个颜色1,bb个颜色2,cc个颜色3时,我们的轨道数,那么我们可以通过背包来累加答案,w[aa][bb][cc]+=w[aa-b[i]][bb][cc]w[aa][bb][cc]+=w[aa][bb-b[i]][cc]w[aa][bb][cc]+=w[aa-b[i]][bb][cc-b[i]]。 /***...
阅读全文
摘要:首先我们知道对于f(x)来说,它是一个k次的多项式,那么f(x)的通项公式可以表示成一个k+1次的式子,且因为f(x)没有常数项,所以我们设这个式子为 f(x)=Σ(a[i]*x^i) (1#include #include #define LL long long#define maxk 150#define P 1234567891using namespace std;struct mat{int n,m;int a[maxk][maxk];mat (int n,int m):n(n),m(m){memset(a,0,sizeof a);};};int K,S,N,D;int ...
阅读全文
摘要:我们对这个函数求二阶导数,发现他的二阶导数是恒大于0的,那么他的导数是单调的,且在某时刻为0,那么这时的x值就是极值处的x值,其实题目说了,有最小值,那么我们三分水过去就好了。 反思:精度不够,因为是log3的,所以的40次循环就WA,50次就可以A。//By BLADEVIL#include #include using namespace std;int task;double y;double f(double x) { return (6*x*x*x*x*x*x*x+8*x*x*x*x*x*x+7*x*x*x+5*x*x-y*x);}int main() { scan...
阅读全文
摘要:我们可以发现这个函数是单增的,那么这样二分就好了。 反思:刚转C++,不会用scanf读入实数。(scanf("%lf",&y))//By BLADEVIL#include #include using namespace std;double f(double x) { return (8*x*x*x*x+7*x*x*x+2*x*x+3*x+6);}int task,y;int main() { scanf("%d",&task); double left=f(0),right=f(100); while (task--) { cin&
阅读全文
摘要:我们可以将这个问题转化为在n维空间中一共放m个n维球,求这m个球最多将这个空间分为不同的几个部分。 那么我们设w[i][j]代表i为空间放j个球分为的部分,那么w[i][j]=w[i][j-1]+w[i-1][j-1],我们考虑当前第j个球所产生的新的部分,在n维空间中,放一个n维球,这个球和其他n维球的相交的部分会降维变成n-1维,类似于3维空间球体相交部分为面,那么我们新加这个球最多可以和剩下的j-1个球都相交,且相交的部分为i-1维,那么这个问题就转化成了在i-1维中,j-1个球最多将这个空间分成多少部分,也就是w[i-1][j-1]。/**********************...
阅读全文
摘要:首先如果我们能处理出来i,j段能不能消掉,这样就可以直接dp转移了,设w[i]为前i为最少剩下多少,那么w[i]=w[j-1] (flag[j][i])。 现在我们来求flag[i][j],首先我们可以把字符串组建立trie然后处理在串L中从left位置开始的所有的flag,那么我们可以在trie上一直往下走,每到一个标记的点就将当前的flag[left][right]设为1,那么这样可以处理出连续可以消掉的字符串,然后就处理对于类似L为abcde,字符串组为ade,bc这样可以先消一个,然后再消的情况,这样我们可以发现,如果对于当前的left,right存在flag[i][right]...
阅读全文
摘要:类似于1014,用splay维护这个序列,维护每个节点为根的子树的hash值,对于一个询问二分答案判断就行了。 反思:询问的时候因为是原序列的x,y,所以开始的时候直接splay(x-1)了,后来发现这是不对的,因为可能在x前插入一些东西,所以需要麻烦些,先splay(x),然后提出来右端点为size[son[rot][0]]+1+len,然后再splay(find(size[son[rot][0]]+1))。/**************************************************************Problem: 2258User: BLADEVIL...
阅读全文
摘要:首先可以二分答案,将最优性问题转化为判定性问题。 对于二分到的边长,我们可以把所有的点看成一个大的矩形,这个矩形为包括所有点的最小矩形,那么贪心的想,3个正方形,第一个肯定放在这个矩形其中的一角,然后去掉覆盖的点,然后再求出一个矩形,然后再枚举放在哪一角,去掉之后判断剩下的是否可以由一个正方形覆盖就行了。 反思:没画图,边界算的不对,而且枚举完两个正方形之后要判下是否没有没覆盖的点了。另外提供神样例 4 1 1 -1 -1 1 -1 -1 1答案是2。/**************************************************************Probl...
阅读全文
摘要:首先我们可以用splay来维护这个字符串,那么对于某两个位置的lcp,维护每个节点的子树的hash,然后二分判断就好了。/**************************************************************Problem: 1014User: BLADEVILLanguage: C++Result: AcceptedTime:4468 msMemory:3640 kb****************************************************************///By BLADEVIL#include #inclu..
阅读全文
摘要:比较容易看出来先建立ac自动机,然后在自动机上做DP,设w[0..1][i][j]为当前不包括/包括字典中的字符串,当前在自动机中走到第i个节点,完成的文本的长度为j的方案数,那么比较容易的转移w[i|j->child->cnt][j->child][k+1]+=w[i][j][k]。 /**************************************************************Problem: 1030User: BLADEVILLanguage: C++Result: AcceptedTime:200 msMemory:25596 kb**
阅读全文
摘要:首先比较明显的是我们可以将字符串组建立ac自动机,那么对于询问s1字符串在s2字符串中出现的次数,就是在以s1结尾为根的fail tree中,子树有多少个节点是s2的节点,这样我们处理fail tree的dfs序,然后用BIT维护,但是如果只是在线处理询问的话会tle,因为每个询问需要将节点的每一位在BIT中都修改,那么我们就浪费了好多性质,因为对于好多字符串拥有较长的LCP,那么我们可以模拟建trie的过程在自动机上跑,每遇到一个添加的字符,就解决所有询问为某字符串在该字符串中出现的次数,这样就可以了。/******************************************..
阅读全文