zoukankan      html  css  js  c++  java
  • Luogu P5665 划分

    MD今天和陈指导一起看了下觉得真是血妈简单,不过考场上还要写高精我估计就直接放弃了,现在肯定直接用__int128水了

    (f_{i,j})表示上一次取的点是(i),其对应的决策点为(j)的答案,显然(f_{i,j}=min { f_{j,k}+operatorname{sum}(j,i)})

    很显然我们可以把(f_{i,j})看作一个(f_i),设其最优决策点为(pos_i),结合柯西不等式(a^2+b^2<(a+b)^2)我们容易发现这个转移具有决策单调性(猜都猜出来了),每个位置最右边的决策点是最优的

    考虑用单调队列维护最右边的前驱,记(pfx_i)(sum_{j=1}^i a_j),若(pfx_i-pfx_{q_{H+1}}ge pfx_{q_{H+1}}-pfx_{pos_{q_{H+1}}})就可以移动前驱,移下项我们发现只要维护(2 imes pfx_i-pfx_{pos_i})单调递增即可

    #include<bits/stdc++.h>
    #define RI register int
    #define CI const int&
    #define calc(x) (2LL*pfx[x]-pfx[pos[x]])
    using namespace std;
    const int N=4e7+5,M=1e5+5;
    int n,tp,m,x,y,z,b[N],l[M],r[M],p[M],q[N],pos[N]; long long pfx[N];
    inline void write(__int128 x)
    {
    	if (x>9) write(x/10); putchar(x%10+'0');
    }
    int main()
    {
    	RI i,j; scanf("%d%d",&n,&tp); if (!tp)
    	for (i=1;i<=n;++i) scanf("%d",&x),pfx[i]=pfx[i-1]+x; else
    	{
    		scanf("%d%d%d%d%d%d",&x,&y,&z,&b[1],&b[2],&m);
    		for (i=3;i<=n;++i) b[i]=(1LL*x*b[i-1]+1LL*y*b[i-2]+z)&((1<<30)-1);
    		for (i=1;i<=m;++i) scanf("%d%d%d",&p[i],&l[i],&r[i]);
    		for (i=j=1;j<=m;++j) while (i<=p[j])
    		pfx[i]=pfx[i-1]+b[i]%(r[j]-l[j]+1)+l[j],++i;
    	}
    	RI H=1,T=1; for (i=1;i<=n;++i)
    	{
    		while (H<T&&calc(q[H+1])<=pfx[i]) ++H; pos[i]=q[H];
    		while (H<T&&calc(q[T])>calc(i)) --T; q[++T]=i;
    	}
    	__int128 ans=0; for (i=n;i;i=pos[i])
    	ans+=(__int128)(pfx[i]-pfx[pos[i]])*(pfx[i]-pfx[pos[i]]);
    	return write(ans),0;
    }
    
  • 相关阅读:
    archlinux安装nvidia-1050ti闭源驱动教程,亲测
    键盘键码对照
    解决manjaro无法外接显示器
    windows下的上帝模式,很好用,细想,很恐怖啊
    高效率编辑器 Vim——操作篇,非常适合 Vim 新手
    linux rand application
    数组和对象常用API
    JsBridge的异步不执行的处理--promise异步变同步
    js根据数组对象中某个元素合并数组
    js/vue 高德地图绘制驾车路线图
  • 原文地址:https://www.cnblogs.com/cjjsb/p/13928664.html
Copyright © 2011-2022 走看看