• UVa 1400


    线段树区间合并,惟一不满意的就是做的拖的时间太长,并且写出来代码没有一边过的自信,能力是需要培养的,rush自己一把吧。
    此外,一直WA的原因是越界的问题,这种考察数据范围后,每个Int需要注意替换成Long Long

    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cstdint>
    #include <cassert>
    #include <cmath>
    #include <string>
    #include <stack>
    #include <map>
    #include <set>
    #include <deque>
    #include <unordered_map>
    using namespace std;
    
    typedef long long LL;
    
    const LL INF= 1LL<<60;
    const int maxn= 500000+5;
    
    inline LL GetS(int l, int r);
    struct Seg
    {
    	int l, r;
    	Seg(int ll= 0, int rr= 0) : l(ll), r(rr) {}
    	bool operator < (const Seg &rhs) const
    	{
    		LL lv= GetS(l, r), rv= GetS(rhs.l, rhs.r);
    		if (lv < rv){
    			return true;
    		} else if (lv == rv){
    			return l > rhs.l || (l == rhs.l && r > rhs.r);
    		} else{
    			return false;
    		}
    	}
    };
    struct Intv
    {
    	Seg ipre, isur, isub;
    	Intv(Seg pre= Seg(), Seg sur= Seg(), Seg sub= Seg())
    		: ipre(pre), isur(sur), isub(sub) 
    	{}
    };
    int n, m;
    LL psum[maxn];
    Seg mpre[maxn<<2], msur[maxn<<2], msub[maxn<<2];
    
    inline LL GetS(int l, int r)
    {
    	return 0 == l ? -INF : psum[r]-psum[l-1];
    }
    inline void PushU(int x, int lo, int hi)
    {
    	int lc= x<<1, rc= x<<1|1;
    
    	mpre[x]= max(mpre[lc], Seg(lo, mpre[rc].r));
    	msur[x]= max(msur[rc], Seg(msur[lc].l, hi));
    
    	msub[x]= max(msub[lc], msub[rc]);
    	msub[x]= max(msub[x], Seg(msur[lc].l, mpre[rc].r));
    }
    void Build(int x, int lo, int hi)
    {
    	if (lo > hi){
    		return;
    	}
    	if (lo == hi){
    		msub[x]= msur[x]= mpre[x]= Seg(lo, hi);
    		return;
    	}
    
    	int mid= (lo+hi)>>1;
    	Build(x<<1, lo, mid);
    	Build(x<<1|1, mid+1, hi);
    	PushU(x, lo, hi);
    }
    Intv Query(int x, int lo, int hi, int L, int R)
    {
    	if (lo > hi){
    		return Intv();
    	}
    	if (L <= lo && hi <= R){
    		return Intv(mpre[x], msur[x], msub[x]);
    	}
    
    	int mid= (lo+hi)>>1;
    	Intv lc, rc;
    	Intv ret;
    	bool lflag= false, rflag= false;
    	if (mid >= L){
    		lc= Query(x<<1, lo, mid, L, R);
    		lflag= true;
    	}
    	if (mid+1 <= R){
    		rc= Query(x<<1|1, mid+1, hi, L, R);
    		rflag= true;
    	}
    
    	if (lflag && rflag){
    		ret.ipre= max(Seg(max(lo, L), rc.ipre.r), lc.ipre);
    		ret.isur= max(Seg(lc.isur.l, min(hi, R)), rc.isur);
    
    		ret.isub= max(lc.isub, rc.isub);
    		ret.isub= max(ret.isub, Seg(lc.isur.l, rc.ipre.r));
    	} else{
    		ret= lflag ? lc : rc;
    	}
    	return ret;
    }
    
    int main(int argc, char const *argv[])
    {
    	Intv ans;
    	int kase= 0;
    	while (2 == scanf("%d%d", &n, &m)){
    		psum[0]= 0;
    		for (int i= 1; i <= n; ++i){
    			scanf("%lld", psum+i);
    			psum[i]+= psum[i-1];
    		}
    
    		Build(1, 1, n);
    
    		printf("Case %d:
    ", ++kase);
    		int s, e;
    		while (m--){
    			scanf("%d%d", &s, &e);
    			ans= Query(1, 1, n, s, e);
    			printf("%d %d
    ", ans.isub.l, ans.isub.r);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    英语语法学习笔记之名词
    2016年回顾2017年目标之流水账
    英语单词词性
    本机tomcat的server.xml被还原的问题及解决办法
    关闭英文拼写检查,关闭xml验证
    eclipse运行速度优化(解决狂读盘、发布慢、CPU100%等问题)
    mysql中,通过脚本设置表的自增列,及自增步长
    Eclipse调试 : step into,step over,step return 说明
    几个分布方法及距离方法
    国内其他的maven库
  • 原文地址:https://www.cnblogs.com/Idi0t-N3/p/15238312.html
Copyright © 2020-2023  润新知