POJ-3277: City Horizon
keyword
座標圧縮 segment tree C++
問題概要
a,b(0
解法
座標圧縮してsegment treeに突っ込む。区間に対する更新処理と点に対する最大値が求められればよい。segment treeの部分は蟻本を参考にして書いた。segment treeの配列のサイズを勘違いして通すのに時間がかかった。
#include <cstdio> #include <algorithm> #include <vector> using namespace std; const int MAX_N = 40009; typedef long long int64; vector<int> nums; int dat[8*MAX_N]; int fs[MAX_N], ts[MAX_N], hs[MAX_N]; int N, M, RMQ_N; int pack(int n){ return distance(nums.begin(), lower_bound(nums.begin(), nums.end(), n)); } void init(){ for(int i=0; i<N; i++){ nums.push_back(fs[i]); nums.push_back(ts[i]); } sort(nums.begin(),nums.end()); nums.erase(unique(nums.begin(), nums.end()), nums.end()); M = nums.size(); RMQ_N = 1; while(RMQ_N < M) RMQ_N *= 2; } int64 query(int k){ k += RMQ_N - 1; int ret = dat[k]; while(k > 0){ k = (k-1)/2; ret = max(ret, dat[k]); } return (int64)ret; } void update(int a, int b, int h, int k, int l, int r){ if(r <= a || b <= l) return ; if(a <= l && r <= b){ dat[k] = max(dat[k], h); } else{ update(a,b,h,k*2+1,l,(l+r)/2); update(a,b,h,k*2+2,(l+r)/2,r); } } void update(int from, int to, int h){ update(from, to, h, 0, 0, RMQ_N); } int64 solve(){ init(); for(int i=0; i<N; i++){ update(pack(fs[i]), pack(ts[i]), hs[i]); } int64 ans = 0; for(int i=0; i<M-1; i++){ ans += (nums[i+1] - nums[i])*query(i); } return ans; } int main(){ scanf("%d",&N); for(int i=0; i<N; i++) scanf("%d%d%d",fs+i,ts+i,hs+i); printf("%lld\n",solve()); return 0; }