Intervals
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 22503 | Accepted: 8506 |
Description
You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn.
Write a program that:
reads the number of intervals, their end points and integers c1, ..., cn from the standard input,
computes the minimal size of a set Z of integers which has at least
ci common elements with interval [ai, bi], for each i=1,2,...,n,
writes the answer to the standard output.
Input
The
first line of the input contains an integer n (1 <= n <= 50000) --
the number of intervals. The following n lines describe the intervals.
The (i+1)-th line of the input contains three integers ai, bi and ci
separated by single spaces and such that 0 <= ai <= bi <= 50000
and 1 <= ci <= bi - ai+1.
Output
The
output contains exactly one integer equal to the minimal size of set Z
sharing at least ci elements with interval [ai, bi], for each
i=1,2,...,n.
Sample Input
5 3 7 3 8 10 3 6 8 1 1 3 1 10 11 1
Sample Output
6
Source
设 s[i]表示集合中小于等于i的元素个数, u v w s[v]-s[u-1]>=w;
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <string> 7 #include <vector> 8 #include <set> 9 #include <map> 10 #include <queue> 11 #include <stack> 12 #include <sstream> 13 #include <iomanip> 14 using namespace std; 15 const int INF=0x4fffffff; 16 const int EXP=1e-6; 17 const int MS=50005; 18 19 struct edge 20 { 21 int u,v,w; 22 }edges[10*MS]; 23 24 int maxv,minv; 25 int dis[MS]; 26 int esize,n; 27 28 bool bellman() 29 { 30 memset(dis,0,sizeof(dis)); 31 bool flag=true; 32 int cnt=0; 33 while(flag) 34 { 35 flag=false; //表示没有更新了 36 37 if(cnt++>n) //更新次数大于n-1, 38 return false; 39 for(int i=0;i<esize;i++) 40 { 41 if(dis[edges[i].u]+edges[i].w<dis[edges[i].v]) 42 { 43 dis[edges[i].v]=dis[edges[i].u]+edges[i].w; 44 flag=true; 45 } 46 } 47 48 //0<=s[i]-s[i-1]<=1 这些边可以不用存储 49 50 // i-1 -->i 1 51 52 for(int i=minv;i<=maxv;i++) 53 { 54 if(dis[i-1]+1<dis[i]) 55 { 56 dis[i]=dis[i-1]+1; 57 flag=true; 58 } 59 } 60 61 // i--> i-1 0 62 63 for(int i=maxv;i>=minv;i--) 64 { 65 if(dis[i]<dis[i-1]) 66 { 67 dis[i-1]=dis[i]; 68 flag=true; 69 } 70 } 71 } 72 return true; 73 } 74 75 76 77 int main() 78 { 79 while(scanf("%d",&n)!=EOF) 80 { 81 int u,v,w; 82 esize=0; 83 maxv=0; 84 minv=INF; 85 for(int i=0;i<n;i++) 86 { 87 scanf("%d%d%d",&u,&v,&w); 88 // s[i]表示集合中小于等于i的元素个数 89 //s[v]-s[u-1]>=w; v->u-1 -w; 90 edges[esize].u=v; 91 edges[esize].v=u-1; 92 edges[esize++].w=-w; 93 if(v>maxv) 94 maxv=v; 95 if(u<minv) 96 minv=u; 97 } 98 bellman(); 99 printf("%d\n",dis[maxv]-dis[minv-1]); 100 } 101 return 0; 102 }