zoukankan      html  css  js  c++  java
  • 「ROI 2018 Day 1」Innophone (分块+斜率优化)

    「ROI 2018 Day 1」Innophone (分块+斜率优化)

    首先可以想到对于(x_i)排序,枚举(a)为某一个(x_i),那么可以将余下的部分分给(b)计算贡献

    如果将(y_i)倒序排成(A_i,iin [1,k]),那么枚举(b)为某一个(A_i)时的贡献就是(icdot A_i)

    同时要维护一个插入(A_i)的操作,可以固定(A_i),维护一个后缀个数加一的操作

    (icdot A_i),同时维护(i ightarrow i+1)容易让人联想到斜率优化,而区间修改的斜率优化常见的可以用分块来维护

    具体的,可以分为两个操作来维护:

    1.下传所有(tag),同时块内建立凸包

    2.块内权值(+1),同时在凸包上完成查询,打上tag

    由于随着下标,权值存在单调性,所以构建凸包应该是比较简单的

    同时查询时的斜率为整个块标记的值,查询有单调性,可以直接移动队列头完成

    因此维护斜率优化是线性完成的,总复杂度为(O(nsqrt n))

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair <int,int> Pii;
    #define reg register
    #define pb push_back
    #define mp make_pair
    #define Mod1(x) ((x>=P)&&(x-=P))
    #define Mod2(x) ((x<0)&&(x+=P))
    #define rep(i,a,b) for(reg int i=a,i##end=b;i<=i##end;++i)
    #define drep(i,a,b) for(reg int i=a,i##end=b;i>=i##end;--i)
    template <class T> inline void cmin(T &a,const T &b){ ((a>b)&&(a=b)); }
    template <class T> inline void cmax(T &a,const T &b){ ((a<b)&&(a=b)); }
    
    char IO;
    template <class T=int> T rd(){
    	T s=0; int f=0;
    	while(!isdigit(IO=getchar())) if(IO=='-') f=1;
    	do s=(s<<1)+(s<<3)+(IO^'0');
    	while(isdigit(IO=getchar()));
    	return f?-s:s;
    }
    
    const int N=2e5+10,SN=600;
    
    int n,len;
    Pii A[N];
    int h[N],hc;
    
    int s[N];
    struct Node{
    	int l,r,tag;
    	int Q[SN],L,R;
    	ll Val(int x) {
    		return 1ll*h[x]*(s[x]+tag);
    	}
    	ll Init() {
             // 重新构建凸包
          	//插入是静态的,查询是单调的,可以线性维护
    		ll ans=0;
    		rep(i,l,r) cmax(ans,1ll*(s[i]+=tag)*h[i]);
    		tag=0,L=1,R=0;
    		drep(i,r,l) {
    			while(L<R && (Val(Q[R])-Val(Q[R-1]))*(h[i]-h[Q[R]]) <= (Val(i)-Val(Q[R]))*(h[Q[R]]-h[Q[R-1]])) R--;
    			Q[++R]=i;
    		}
    		return ans;
    	}
    	ll Add(){
             
    		tag++;
    		while(L<R && Val(Q[L+1])>=Val(Q[L])) L++;
    		return Val(Q[L]);
    	}
    } S[SN];
    
    ll ans,Ans;
    void Add(int x) { // 向A_i中插入x,维护后缀+1操作
    	int p=x/len;
    	rep(i,x,min(hc,(p+1)*len-1)) s[i]++;
    	cmax(ans,S[p].Init());
    	rep(i,p+1,hc/len) cmax(ans,S[i].Add());
    }
    
    int main(){
    	n=rd();
    	rep(i,1,n) A[i].first=rd(),A[i].second=rd();
    	sort(A+1,A+n+1);
    	rep(i,1,n) h[++hc]=A[i].second;
    	sort(h+1,h+hc+1,greater<int>()),hc=unique(h+1,h+hc+1)-h-1;
    	rep(i,1,n) A[i].second=lower_bound(h+1,h+hc+1,A[i].second,greater<int>())-h;
    	len=sqrt(hc);
    	rep(i,0,hc/len) S[i].l=max(1,i*len),S[i].r=min(hc,(i+1)*len-1),S[i].Init();
    
    	rep(i,1,n+1) {
    		cmax(Ans,1ll*(n-i+1)*A[i].first+ans);
    		if(i<=n) Add(A[i].second);
    	}
    	printf("%lld
    ",Ans);
    }
    
  • 相关阅读:
    题解 BZOJ1026 & luogu P2657 [SCOI2009]windy数 数位DP
    BZOJ 1867 [Noi1999]钉子和小球 DP
    P5057 [CQOI2006]简单题 前缀异或差分/树状数组
    P2051 [AHOI2009]中国象棋 大力DP
    P4208 [JSOI2008]最小生成树计数
    BZOJ 2440 [中山市选2011]完全平方数 二分+容斥
    Luogu P1951 收费站_NOI导刊2009提高(2) 二分 最短路
    Luogu P3527 [POI2011]MET-Meteors 整体二分
    Luogu P4109 [HEOI2015]定价 贪心
    Luogu P2114_[NOI2014]起床困难综合症 贪心
  • 原文地址:https://www.cnblogs.com/chasedeath/p/14394664.html
Copyright © 2011-2022 走看看