zoukankan      html  css  js  c++  java
  • 【BZOJ 2216】【POI 2011】Lightning Conductor

    http://www.lydsy.com/JudgeOnline/problem.php?id=2216
    学习了一下决策单调性。
    这道题决策单调性比较明显,不详细证了。
    对于一个决策i,如果在i之前的j处进行决策,那么i之后的决策都不可能在j之前。
    利用决策单调性,可以维护每个决策点形成的单调栈,更新决策点也是利用单调栈的信息在原数组上二分。
    这道题假设j<i,然后扫两遍就可以了,时间复杂度(O(nlog n))
    看网上的大爷都写得单调队列?整体二分?orz

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    const int N = 500003;
    
    int st[N], top, stn[N];
    
    void solve(int n, int *a, int *f) {
    	top = 0;
    	for (int i = 1; i <= n; ++i) {
    		int left = 1, right = top, mid;
    		while (left < right) {
    			mid = (left + right + 1) >> 1;
    			if (stn[mid] <= i) left = mid;
    			else right = mid - 1;
    		}
    		
    		if (top) f[i] = max(ceil(sqrt(i - st[left])) + a[st[left]] - a[i], 0.0);
    		while (top && stn[top] > i && sqrt(stn[top] - st[top]) + a[st[top]] < sqrt(stn[top] - i) + a[i]) --top;
    		
    		if (!top) {st[++top] = i; stn[top] = i + 1; continue;}
    		
    		left = max(i + 1, stn[top] + 1); right = n + 1;
    		while (left < right) {
    			mid = (left + right) >> 1;
    			if (sqrt(mid - st[top]) + a[st[top]] < sqrt(mid - i) + a[i]) right = mid;
    			else left = mid + 1;
    		}
    		
    		if (left <= n) st[++top] = i, stn[top] = left;
    	}
    }
    
    int a[N], n, f1[N], f2[N];
    
    int main() {
    	scanf("%d", &n);
    	for (int i = 1; i <= n; ++i) scanf("%d", a + i);
    	solve(n, a, f1);
    	reverse(a + 1, a + n + 1);
    	solve(n, a, f2);
    	reverse(f2 + 1, f2 + n + 1);
    	
    	for (int i = 1; i <= n; ++i) printf("%d
    ", max(f1[i], f2[i]));
    	return 0;
    }
    
  • 相关阅读:
    IOS之UIAlert​Controller
    IOS实现弹出菜单效果MenuViewController(背景 景深 弹出菜单)
    IOS之正则表达式
    死锁与递归锁
    线程与进程的一些应用
    开启线程的两种方式
    互斥锁
    进程的队列
    模拟抢票系统
    Python并发编程__多进程
  • 原文地址:https://www.cnblogs.com/abclzr/p/6675047.html
Copyright © 2011-2022 走看看