zoukankan      html  css  js  c++  java
  • NORMA2

    传送门

    我们考虑分治,处理(solve(l,r))时算出所有过(mid)区间的贡献

    考虑先枚举左侧点,同时预处理数组

    (s_1=sumlimits_{i=mid+1}^{r}(i-mid)*max{a[mid+1->i]})
    (s_1^{'}=sumlimits_{i=mid+1}^{r}max{a[mid+1->i]})

    同时(s2,s3)分别求最大值和最大值乘最小值

    枚举区间的左端点出,找到(mid)右侧第一个小于左侧最小值的点(j)和大于左侧最大值的点(k)

    不失一般性的考虑(j<k)的情况

    为了方便,我们让(j=j-1,k=k-1)

    对于(mid+1->j)的部分,最大值和最小值在枚举左端点的时候可以处理出来

    这部分贡献是等差数列求和乘最大值和最小值

    [minn*maxn*frac{((mid+1-l+1)+(j-l+1))*(j-(mid+1)+1)}{2} ]

    对于(j+1->k)我们的最大值仍然是(maxn),最小值发生了变化

    [maxn*((s_1[k]-s_1[j])+(mid-l+1)*(s_1^{`}[k]-s_1^{`}[j])) ]

    最后(k+1->r)这部分完全和左边值无关了

    [((s_3[r]-s_3[k])+(mid-l+1)*(s_3^{`}[r]-s_3^{`}[k])) ]

    然后分治下去就好了,注意判断(l==r)的边界

    #include<bits/stdc++.h>
    using namespace std;
    namespace red{
    #define int long long
    #define ls(p) (p<<1)
    #define rs(p) (p<<1|1)
    #define y1 qwq 
    	inline int read()
    	{
    		int x=0;char ch,f=1;
    		for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
    		if(ch=='-') f=0,ch=getchar();
    		while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    		return f?x:-x;
    	}
    	const int N=5e5+10,p=1e9;
    	int n,ans;
    	int a[N],s1[N],s2[N],s3[N],s1_[N],s2_[N],s3_[N];
    	inline void sakura(int l,int r)
    	{
    		if(l==r){(ans+=a[l]*a[l]%p)%=p;return;}
    		int mid=(l+r)>>1,minn=a[mid],maxn=a[mid],i=mid,j=mid,k=mid;
    		int t1=a[mid+1],t2=a[mid+1];
    		s1[mid]=s2[mid]=s3[mid]=s1_[mid]=s2_[mid]=s3_[mid]=0;
    		for(int i=mid+1;i<=r;++i)
    		{
    			t1=min(t1,a[i]),t2=max(t2,a[i]);
    			(s1[i]=s1[i-1]+t1*(i-(mid+1)+1)%p)%=p;
    			(s1_[i]=s1_[i-1]+t1)%=p;
    			
    			(s2[i]=s2[i-1]+t2*(i-(mid+1)+1)%p)%=p;
    			(s2_[i]=s2_[i-1]+t2)%=p;
    			
    			(s3[i]=s3[i-1]+t1*t2%p*(i-(mid+1)+1)%p)%=p;
    			(s3_[i]=s3_[i-1]+t1*t2%p)%=p;
    		}
    		while(i>=l)
    		{
    			minn=min(minn,a[i]),maxn=max(maxn,a[i]);
    			while(j<r&&a[j+1]>minn) ++j;
    			while(k<r&&a[k+1]<maxn) ++k;
    			int w1=min(j,k),w2=max(j,k);
    			if(w1>mid) (ans+=minn*maxn%p*((mid+1-i+1+w1-i+1)*(w1-(mid+1)+1)/2%p)%p)%=p;
    			if(j>w1) (ans+=minn*((s2[j]-s2[w1]+p)%p+(mid-i+1)*(s2_[j]-s2_[w1]+p)%p)%p)%=p;
    			if(k>w1) (ans+=maxn*((s1[k]-s1[w1]+p)%p+(mid-i+1)*(s1_[k]-s1_[w1]+p)%p)%p)%=p;
    			(ans+=((s3[r]-s3[w2]+p)%p+(mid-i+1)*(s3_[r]-s3_[w2]+p)%p)%p)%=p;
    			--i;
    		}
    		sakura(l,mid);sakura(mid+1,r);
    	}
    	inline void main()
    	{
    		n=read();
    		for(int i=1;i<=n;++i) a[i]=read();
    		sakura(1,n);
    		printf("%lld
    ",ans%p);
    	}
    }
    signed main()
    {
    	red::main();
    	return 0;
    }
    

    (sakura)最好啦

  • 相关阅读:
    bootstrap modal 移除数据
    bootstrap modal 点击头部移动
    js 四舍五入
    js 函数问题
    bootstrap 模态框事件
    Java自定义注解
    JAVA中的System.in
    java 流
    让Mustache支持简单的IF语句
    方法允许多个返回值(.Net Core最新特性,.Net Framework4.7.1版本也有)
  • 原文地址:https://www.cnblogs.com/knife-rose/p/12643797.html
Copyright © 2011-2022 走看看