• BZOJ3745:[COCI2015]Norma


    浅谈离线分治算法:https://www.cnblogs.com/AKMer/p/10415556.html

    题目传送门:https://lydsy.com/JudgeOnline/problem.php?id=3745

    我们对于所有区间,要么在分治的(mid)左边,要么在分治的(mid)右边,我们可以递归去处理。

    所以我们只需要知道怎么快速统计经过(mid)的区间的答案即可。

    我们从大到小枚举区间的左端点(x),然后计算(sumlimits_{y=mid+1}^{r}ans[x][y])(ans[x][y])表示区间([x,y])对答案的贡献。

    假设区间([x,mid])的最小值是(a),最大值(b)

    区间([mid+1,q])的最小值比(a)大,最大值比(b)小。

    区间([q+1,p])的最小值比(a)大,最大值比(b)大,或者最小值比(a)小,最大值比(b)小。

    区间([p+1,r])的最小值小于(a),最大值大于(b)

    (mn[i])表示([mid+1,i])的最小值,(mx[i])表示([mid+1,i])的最大值。

    当右端点落在这三段时,对答案的贡献分别计算。

    第一段([mid+1,q])对答案的贡献:

    (sumlimits_{i=mid+1}^{q}ab(i-x+1)=frac{ab(mid+2-x)(q-x+1)(q-mid)}{2})

    第二段([q+1,p])对答案的贡献:

    假如这一段最小值比(a)大,最大值比(b)大:

    (sumlimits_{i=q+1}^{p}a*mx[i]*(i-x+1))

    化开得:(a*(sumlimits_{i=q+1}^{p}mx[i]*i-(x-1)sumlimits_{i=q+1}^{p}mx[i]))

    (sum[1][y])表示(sumlimits_{i=mid+1}^{y}mx[i]*i)(sum[2][y])表示(sumlimits_{i=mid+1}^{y}mx[i])

    那么对答案的贡献就可以表示为(a*(sum[1][p]-sum[1][q]-(x-1)*(sum[2][p]-sum[2][q]))

    假如这一段最小值比(a)小,最大值比(b)小,同理可得:

    (sum[3][y])表示(sumlimits_{i=mid+1}^{y}mn[i]*i)(sum[4][y])表示(sumlimits_{i=mid+1}^{y}mn[i])

    对答案的贡献可以表示为(b*(sum[3][p]-sum[3][q]-(x-1)*(sum[4][p]-sum[4][q])))

    第三段对答案的贡献:

    (sumlimits_{i=p+1}^{r}mn[i]*mx[i]*(i-x+1))

    可以化为(sumlimits_{i=p+1}^{r}mx[i]*mn[i]*i-(x-1)*sumlimits_{i=p+1}^{r}mn[i]*mx[i])

    (sum[5][y])表示(sumlimits_{i=mid+1}^{y}mx[i]*mn[i]*i)(sum[6][y])表示(sumlimits_{i=mid+1}^{y}mn[i]*mx[i])

    对答案的贡献可以表示为(sum[5][r]-sum[5][p]-(x-1)*(sum[6][r]-sum[6][p]))

    所以只需要扫一遍就可以统计当前分治层的答案了。

    时间复杂度:(O(nlogn))

    空间复杂度:(O(n))

    代码如下:

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    #define sqr(x) (1ll*(x)*(x)%pps)
    
    const int maxn=5e5+5,pps=1e9,inf=2e9;
    
    int n,ans;
    int sum[7][maxn];
    int num[maxn],mn[maxn],mx[maxn];
    
    int read() {
    	int x=0,f=1;char ch=getchar();
    	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    	for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    	return x*f;
    }
    
    void clear(int pos) {
    	mn[pos]=inf,mx[pos]=-inf;
    	for(int i=1;i<7;i++)
    		sum[i][pos]=0;
    }
    
    int calc(int a,int b) {
    	int c=a+b,d=b-a+1;
    	if(c%2==0)c/=2;
    	else d/=2;
    	return 1ll*c*d%pps;
    }
    
    void solve(int l,int r) {
    	if(l==r) {
    		ans=(ans+sqr(num[l]))%pps;
    		return;
    	}
    	int mid=(l+r)>>1;
    	solve(l,mid),solve(mid+1,r);
    	clear(mid);
    	for(int i=mid+1;i<=r;i++) {
    		mn[i]=min(mn[i-1],num[i]);
    		mx[i]=max(mx[i-1],num[i]);
    		sum[1][i]=(sum[1][i-1]+1ll*mx[i]*i%pps)%pps;
    		sum[2][i]=(sum[2][i-1]+mx[i])%pps;
    		sum[3][i]=(sum[3][i-1]+1ll*mn[i]*i%pps)%pps;
    		sum[4][i]=(sum[4][i-1]+mn[i])%pps;
    		sum[5][i]=(sum[5][i-1]+1ll*mn[i]*mx[i]%pps*i%pps)%pps;
    		sum[6][i]=(sum[6][i-1]+1ll*mn[i]*mx[i]%pps)%pps;
    	}
    	int a=inf,b=-inf,limit1=mid,limit2=mid;
    	for(int x=mid;x>=l;x--) {
    		a=min(a,num[x]),b=max(b,num[x]);
    		while(mn[limit1+1]>=a&&limit1<r)limit1++;
    		while(mx[limit2+1]<=b&&limit2<r)limit2++;
    		int q=min(limit1,limit2),p=max(limit1,limit2);
    		ans=(ans+(1ll*a*b%pps*calc(mid+2-x,q-x+1)%pps))%pps;
    		if(q==limit2)ans=(ans+1ll*a*(sum[1][p]-sum[1][q]-1ll*(x-1)*(sum[2][p]-sum[2][q])%pps)%pps)%pps;
    		else ans=(ans+1ll*b*(sum[3][p]-sum[3][q]-1ll*(x-1)*(sum[4][p]-sum[4][q])%pps)%pps)%pps;
    		ans=(ans+sum[5][r]-sum[5][p]-1ll*(x-1)*(sum[6][r]-sum[6][p])%pps)%pps;
    	}
    }
    
    int main() {
    	n=read();
    	for(int i=1;i<=n;i++)
    		num[i]=read();
    	solve(1,n);ans=(ans+pps)%pps;
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    flask
    redis实战之事物和持久化
    vue 工程从window 到mac
    mysql5.7 group by
    Error creating bean with name 'org.apache.cxf.spring.boot.autoconfigure.CxfAutoConfiguration
    当我回过头
    springmvc 接收json类型的数据封装到map中
    linux 下 home 目录磁盘爆满,rm 后仍然不行
    springboot启动时的一个bug
    vue 使用webpack 打包 出现UnhandledPromiseRejectionWarning: Error: "dependency" is not a valid chunk sort mode at HtmlWebpackPlugin.sortEntryChunks
  • 原文地址:https://www.cnblogs.com/AKMer/p/10426924.html
Copyright © 2020-2023  润新知