• LOJ#6101. 「2017 山东二轮集训 Day1」第二题 题解


    题目链接

    按照最小值分治到两边,然后直接做即可。

    (Theta(nlog n)) , 如果 (Theta(n)) 建笛卡尔树可以做到 (Theta(n)) .

    code :

    #include <bits/stdc++.h>
    #define LL long long
    using namespace std;
    template <typename T> void read(T &x){
    	static char ch; x = 0,ch = getchar();
    	while (!isdigit(ch)) ch = getchar();
    	while (isdigit(ch)) x = x * 10 + ch - '0',ch = getchar();
    }
    inline void write(LL x){if (x > 9) write(x/10); putchar(x%10+'0'); }
    
    const int N = 100005;
    int n,k,a[N],Log[N],mn[N][20];
    struct data{
    	LL ans,r;
    	data(){ ans = r = 0; }
    	inline void add(LL v){ r += v; if (r > 0) ans += ceil(r * 1.0 / k),r -= ceil(r * 1.0 / k) * k;  }
    };
    inline int Mn(int l,int r){
    	static int t; t = Log[r-l+1],l = mn[l][t],r = mn[r-(1<<t)+1][t];
    	return a[l] < a[r] ? l : r;
    }
    data solve(int l,int r,int h){
    	if (l > r) return data();
    	if (l == r){ data tmp; tmp.add(a[l]-h); return tmp; }
    	int p = Mn(l,r); data tmp = solve(l,p-1,a[p]),R = solve(p+1,r,a[p]);
    	tmp.ans += R.ans,tmp.add(R.r),tmp.add((LL)(r-l+1)*(a[p]-h));
    	return tmp;
    }
    int main(){
    	int i,j,x,y;
    	read(n),read(k);
    	for (i = 1; i <= n; ++i) read(a[i]),mn[i][0] = i;
    	for (i = 1; i <= n; ++i){ Log[i] = Log[i-1]; if ((1<<Log[i]+1) < i) ++Log[i]; }
    	for (j = 1; j <= Log[n]; ++j) for (i = 1; i+(1<<j)-1 <= n; ++i)
    		x = mn[i][j-1],y = mn[i+(1<<j-1)][j-1],mn[i][j] = a[x] < a[y] ? x : y;
    	write(solve(1,n,0).ans),putchar('
    ');
    	return 0;
    }
    
  • 相关阅读:
    Vue 常用指令
    Vue起飞前的准备
    Django ORM 高性能查询优化
    Django 缓存、序列化、信号
    关于Django ModelForm渲染时间格式问题
    Django自定义分页并保存搜索条件
    Docker容器中用户权限管理
    Linux三种SSH协议登陆方式
    Docker部署Nextcloud私有网盘
    Zabbix官方部署搭建
  • 原文地址:https://www.cnblogs.com/s-r-f/p/13763647.html
Copyright © 2020-2023  润新知