随笔分类 - 数据结构—单调栈
摘要:把期望改成方案数最后除一下,设h[i]为最大值恰好是i的方案数,那么要求的就是Σh[i]\ i 首先包含其他区间的区间是没有意义的,用单调栈去掉 然后恰好不好求,就改成h[i]表示最大值最大是i的方案数,求Σ(h[i] h[i 1])\ i即可 然后考虑h怎么求,\\( h[i]=\sum_{j=1
阅读全文
摘要:用SA求出height数组,然后发现每个height值都有一个贡献区间(因为点对之间要依次取min) 用单调栈处理出区间,第一问就做完了 然后用并查集维护每个点的贡献(?),从大到小枚举height,因为这样区间是不断增大的所以并查集合并即可 cpp include include include
阅读全文
摘要:把两个串中间加一个未出现字符接起来,然后求SA 然后把贡献统计分为两部分,在排序后的后缀里,属于串2的后缀和排在他前面属于串1的后缀的贡献和属于串1的后缀和排在他前面属于串2的后缀的贡献 两部分分别作,都用单调栈维护一段里的height最小值(因为lcp是排序后两后缀中间height最小值),然后根
阅读全文
摘要:对于每个i,以它为左端点的最优右端点一定是单增的,所以用单调栈维护 具体的,单调栈里放的是和单调的长为d的子段,然后枚举右端点,如果这段的和 当前长为d子段最大的和大于p的话,左端点右移同时注意单调栈里的子段的左端点不能小于当前左端点,需要一起右移 cpp include include using
阅读全文
摘要:用单调递减的栈从后往前扫一遍即可 cpp include include using namespace std; const int N=1000005; int n,s[N],top,a[N],ans[N]; int read() { int r=0,f=1; char p=getchar();
阅读全文
摘要:还以为是dp呢 首先默认答案是n 对于一个影子,如果前边的影子比它高则可以归进前面的影子,高处的一段单算; 和他一样高的话就不用单算了,ans ; 否则入栈
阅读全文
摘要:设f[i]为i不选的最小损失,转移是f[i]=f[j]+e[i[(i j 1 include using namespace std; const int N=100005; int n,m,e[N],q[N],l,r; long long f[N],ans,mn=1e18; int read()
阅读全文
摘要:先考虑只能往一边传播,最后正反两边就行 一向右传播为例,一头牛能听到的嚎叫是他左边的牛中与高度严格小于他并且和他之间没有更高的牛,用单调递减的栈维护即可 cpp include include using namespace std; const int N=50005; int n,a[N],v[
阅读全文
摘要:开一个单调递减的单调栈,然后用sum数组维护每个点的答案,新加点的时候一边退栈一边把退掉的点的sum加进来 cpp include include using namespace std; const int N=800005; int s[N],top,a[N],n,sum[N]; int rea
阅读全文
摘要:强烈安利:http://blog.csdn.net/qq_34637390/article/details/51313126 这篇讲标记讲的非常好,这个标记非常神奇…… 首先last表示扫描到last这个点了,val[x]表示x到last中的最小值,sum[x]表示last分别等于1,2,3....
阅读全文
摘要:参考:https://www.cnblogs.com/lcf 2000/p/6789680.html 这是一个相对码量少的做法,用到了区间修改区间查询的树状数组,详见:www.cnblogs.com/lcf 2000/p/5866170.html 3830447 枚举最大值a[i],找到l[i],r
阅读全文