问题描述
Country A 与 B 是敌对国家,它们正在一场战争中互相发射导弹。
A 国共发射了 N N 枚导弹,其中第 i i 枚的发射时间为 Ta i Tai ,花费 Tac i Taci 的时间 飞到 B 国,并可对 B 国造成 Da i Dai 点损害。
B 国共发射了 M M 枚导弹,其中第 i i 枚的发射时间为 Tb i Tbi ,花费 Tbc i Tbci 的时间 飞到 A 国,并可对 A 国造成 Db i Dbi 点伤害。
不过,两国都有一套导弹防御系统,A 国的导弹防御系统可以在某个连续 TA TA 的时间段内开启(其它时间关闭),B 国的导弹系统可以在某个连续 TB TB 的时 间段内开启(其它时间关闭)。当拦截系统开启时,所有到达该国的导弹会立即 调转方向按照原本的速度飞向对面国家;当拦截系统关闭时,导弹会对该国造成 损害(拦截系统在时间段端点处,即恰好开启和关闭时也被认为是开启的)。
现在 A 国的情报部门探听到 B 国将于时刻 X X 开启导弹系统(在时刻 X+TB X+TB 关闭)。作为 A 国的总统,请你决定何时开启本国的导弹系统,可以使受到的损害最小。
输入格式
每个测试点包含多组数据(不超过 50 组),对于每组数据:
第一行两个整数 TA TA , TB TB ,
第二行一个整数 X X ,
第三行两个整数 N N , M M 。
接下来 N N 行每行三个整数 Ta i Tai ,Tac i Taci ,Da i Dai 。
接下来 M M 行每行三个整数 Tb i Tbi ,Tbc i Tbci ,Db i Dbi 。
输出格式
对于每组数据,输出 A 国受到的最小损害。
样例输入
2 2
2
1 0
1 1 10
4 5
3
2 2
1 2 10
1 5 7
1 3 2
0 4 8
输出格式
0
17
据规模与约定
对于 20%的数据,0<=N,M<=100 0<=N,M<=100 。
对于另外 20%的数据,TA=0 TA=0 。
对于另外 20%的数据,TB=0 TB=0 。
对于 100%的数据,0<=TA,TB,X,Ta i ,Tac i ,Tb i ,Tbc i <=10 8 ,0<=N,M<=10 4 ,1<=Da i ,Db i <=10 4 0<=TA,TB,X,Tai,Taci,Tbi,Tbci<=108,0<=N,M<=104,1<=Dai,Dbi<=104 。
时空限制
1S/512MB
题解
预处理A和B的导弹,看哪些可以被反弹,求出欲反弹导弹需要覆盖哪些地区,然后排序,枚举,优先队列。
1 #include2 using namespace std; 3 const int maxn=10100; 4 long long ta,tb,x,tot,n,m,sum,ans; 5 long long read(){ 6 long long lin = 0; 7 char x= getchar(); 8 while(x<'0' || x > '9'){ 9 x = getchar(); 10 } 11 while(x >= '0' && x <= '9'){ 12 lin = (lin << 1) + (lin << 3) + x - '0'; 13 x = getchar(); 14 } 15 return lin; 16 } 17 struct st{ 18 long long st,en,tim,att; 19 }a[maxn << 1],s[maxn << 1]; 20 bool com(st a,st b){ 21 return a.en < b.en; 22 } 23 void putin(){ 24 for(long long i=1;i<=n;i++){ 25 a[i].st = read(); 26 a[i].tim = read(); 27 a[i].att = read(); 28 a[i].en = 0; 29 if(a[i].st + a[i].tim >= x && a[i].st + a[i].tim <= x + tb){ 30 sum += a[i].att; 31 tot++; 32 s[tot] = a[i]; 33 long long k = (x + tb - a[i].st - a[i].tim) % (a[i].tim << 1); 34 s[tot].en = x + tb - k + a[i].tim; 35 s[tot].st += s[tot].tim << 1; 36 } 37 } 38 for(long long i=1;i<=m;i++){ 39 a[i].st = read(); 40 a[i].tim = read(); 41 a[i].att = read(); 42 a[i].en = 0; 43 tot++; 44 sum += a[i].att; 45 s[tot] = a[i]; 46 long long k = (x + tb - a[i].st) % (a[i].tim << 1); 47 s[tot].en = x + tb - k + a[i].tim; 48 s[tot].st += s[tot].tim; 49 if(s[tot].st + s[tot].tim < x || s[tot].st + s[tot].tim > x + tb){ 50 s[tot].en = s[tot].st; 51 } 52 } 53 } 54 bool operator <(st a,st b){ 55 return a.st > b.st; 56 } 57 int main(){ 58 while(cin>>ta>>tb){ 59 sum = 0; 60 tot = 0; 61 x = read(); 62 n = read(); 63 m = read(); 64 putin(); 65 sort(s+1,s+1+tot,com); 66 ans = sum; 67 priority_queue q; 68 for(long long i=1;i<=tot;i++){ 69 q.push(s[i]); 70 sum -= s[i].att; 71 while(q.top().st < s[i].en - ta && !q.empty()){ 72 sum += q.top().att; 73 q.pop(); 74 } 75 ans = min(ans,sum); 76 } 77 cout< endl; 78 } 79 return 0; 80 }