标签:tor 二进制 for can uil min its std date
题意:给定一个区间范围[M,E],接下来有n行输入,每行输入三个数值:T1,T2,S,表示覆盖区间[T1,T2]的代价为S,要求你求出覆盖区间[M,E]的最小代价,如果不能覆盖,则输出-1.
// #include<bits/stdc++.h> #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> // for memset #include <vector> // push_back() // vector<int>().swap(v); #include <set> //multiset set<int,greater<int>> //big->small #include <map> #include <stack> // top() #include <queue> // front() // priority_queue<T,vector<T>,greater<T> > #include <cmath> // auto &Name : STLName Name. #include <utility> #include <sstream> #include <string> // __builtin_popcount (ans); // 获取某个数二进制位1的个数 #include <cstdlib> // rand() #define IOS ios_base::sync_with_stdio(0); cin.tie(0) #define lowbit(x) (x&(-x)) using namespace std; typedef long long ll; const int INF = 0x3f3f3f3f; struct node { int l,r,v; }a[10000 + 9]; bool cmp(const node a,const node b) { return a.r<b.r; } int tr[880000]; void build(int l,int r,int o) { if(l==r) { tr[o]=INF; return; } int m=(l+r)/2; build(l,m,o<<1); build(m+1,r,o<<1|1); tr[o]=min(tr[o<<1],tr[o<<1|1]); return; } int query(int l,int r,int o,int x,int y) { if(x<=l&&r<=y) return tr[o]; int m=(l+r)>>1; int ans=INF; if(x<=m) ans=min(ans,query(l,m,o<<1,x,y)); if(y>m) ans=min(ans,query(m+1,r,o<<1|1,x,y)); return ans; } void update(int l,int r,int o,int x,int v) { if(l==r) { tr[o]=v; return; } int m=(l+r)>>1; if(x<=m) update(l,m,o<<1,x,v); else update(m+1,r,o<<1|1,x,v); tr[o]=min(tr[o<<1],tr[o<<1|1]); } int main(void) { int n,s,t; scanf("%d%d%d",&n,&s,&t); t-=s-2; for(int i=1;i<=n;i++) { scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].v); a[i].l-=s-2; a[i].r-=s-2; } s=2; sort(a+1,a+1+n,cmp); build(1,t,1); update(1,t,1,1,0); for(int i=1;i<=n;i++) { int v1=query(1,t,1,a[i].l-1,a[i].r-1); int v2=query(1,t,1,a[i].r,a[i].r); if(v1+a[i].v<v2) update(1,t,1,a[i].r,v1+a[i].v); } int ans=query(1,t,1,t,t); if(ans==INF) printf("-1\n"); else printf("%d\n",ans); return 0; }
标签:tor 二进制 for can uil min its std date
原文地址:https://www.cnblogs.com/jaszzz/p/13019146.html