zoukankan      html  css  js  c++  java
  • P6406 [COCI2014-2015] Norma 分治+数学

    题意:

    戳这里

    分析:

    • 暴力

    (O(n log n)) 预处理 ST表 然后 (O(n^2)) 枚举左右端点

    • 正解

    我们要优化统计答案的复杂度,也就是说我们需要大概 (O(n log n)) 的复杂度 来统计答案

    很容易想到每一个点作为最大值和最小值的影响是一段区间,那么我们就递归通过分治来统计区间的贡献,和 CDQ 分治的思想差不多,我们只需要统计跨过区间中点的影响,剩下的递归下去

    具体来说,每一次分治中,我们枚举左端点 (i) ,统计以 (i) 为左端点的序列的答案,分三种情况讨论 , 默认 (ple q)

    变量声明:

    mx = $ max(a_idots a_{mid})$ ; mn = $ min(a_idots a_{mid})$

    mna = (sum mn) ; mnb = (sum mn imes i)

    mxa = (sum mx) ; mxb = $sum mx imes i $

    mma = (sum mx imes mn) ; mmb = (sum mx imes mn imes i)

    p 表示满足 (mn leqslant min { a[mid!+!1] cdots a[j] }) 的最大的 p 的位置
    q 表示满足 (mx geqslant max { a[mid!+!1] cdots a[k] }) 的最大的 q 的位置。

    1. (mx,mn) 都取 ([mid+1,p])

    (ans Leftrightarrow sum mn imes mx imes (j-i+1))

    1. (mx)(mn) 不取 ([p,q])

    (ans Leftrightarrow mx imes sum min_j imes (j-i+1))

    1. (mx,mn) 都不取 ([q,r])

    (ansLeftrightarrow sum max_j imes min_j imes (j-i+1))

    代码:

    #include<bits/stdc++.h>
    
    using namespace std;
    
    namespace zzc
    {
    	inline int read()
    	{
    		int x=0,f=1;char ch=getchar();
    		while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
    		while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    		return x*f;
    	}
    	
    	const int maxn = 5e5+5;
    	const long long mod = 1e9;
    	long long a[maxn],mxa[maxn],mxb[maxn],mna[maxn],mnb[maxn],mma[maxn],mmb[maxn];
    	long long ans,n,mn,mx;
    	
    	void qm(long long x){return (void)(ans=(ans+x>=mod?ans+x-mod:ans+x));}
    	long long S(long long l,long long r){return (long long)(l+r)*(r-l+1)/2%mod;}
    	
    	void solve(int l,int r)
    	{
    		if(l==r){return (void)(qm(a[l]*a[l]%mod));}
    		long long mid=(l+r)>>1;
    		solve(l,mid);solve(mid+1,r);
    		mn=mod;mx=0;
    		mxa[mid]=mxb[mid]=mna[mid]=mnb[mid]=mma[mid]=mmb[mid]=0;
    		for(int j=mid+1;j<=r;j++)
    		{
    			mn=min(mn,a[j]);mx=max(mx,a[j]);
    			mxa[j]=(mxa[j-1]+mx)%mod;
    			mxb[j]=(mxb[j-1]+mx*j%mod)%mod;
    			mna[j]=(mna[j-1]+mn)%mod;
    			mnb[j]=(mnb[j-1]+mn*j%mod)%mod;
    			mma[j]=(mma[j-1]+mn*mx%mod)%mod;
    			mmb[j]=(mmb[j-1]+mn*mx%mod*j%mod)%mod;
    		}
    		mn=mod;mx=0;
    		for(int q=mid+1,p=mid+1,i=mid;i>=l;i--)
    		{
    			mn=min(mn,a[i]);mx=max(mx,a[i]);
    			while(p<=r&&mn<a[p]) p++;
    			while(q<=r&&mx>a[q]) q++;
    			if(p<q)
    			{
    				qm(mn*mx%mod*S(mid-i+2,p-i)%mod);
    				qm((mnb[q-1]-mnb[p-1]+mod)*mx%mod+(1-i+mod)*mx%mod*(mna[q-1]-mna[p-1]+mod)%mod);
    				qm((mmb[r]-mmb[q-1]+mod)%mod+(1-i+mod)%mod*(mma[r]-mma[q-1])%mod);
    			}
    			else
    			{
    				qm(mn*mx%mod*S(mid-i+2,q-i)%mod);
    				qm((mxb[p-1]-mxb[q-1]+mod)*mn%mod+(1-i+mod)*mn%mod*(mxa[p-1]-mxa[q-1]+mod)%mod);
    				qm((mmb[r]-mmb[p-1]+mod)%mod+(1-i+mod)%mod*(mma[r]-mma[p-1]+mod)%mod);
    			} 
    		}
    	}
    	
    	void work()
    	{
    		n=read();
    		for(int i=1;i<=n;i++) a[i]=read();
    		solve(1,n);
    		printf("%lld
    ",ans%mod);
    	}
    
    }
    
    int main()
    {
    	zzc::work();
    	return 0;
    }
    
    
  • 相关阅读:
    推荐两款好用的反编译工具(Luyten,Jadx)
    在windows上运行linux
    Spring IOC的理解
    Django 13 admin和auth系统、权限问题
    Django 12 中间件、上下文处理器和admin后台
    Django 11 form表单(状态保持session、form表单及注册实现)
    Django 10 GET和POST(HttpRequest对象,GET和POST请求,文件上传,HttpResponse对象的cookie)
    Django 09 博客小案例
    Django 解答 01 (pycharm创建项目)
    Django 08 Django模型基础3(关系表的数据操作、表关联对象的访问、多表查询、聚合、分组、F、Q查询)
  • 原文地址:https://www.cnblogs.com/youth518/p/14050249.html
Copyright © 2011-2022 走看看