链接: https://cn.vjudge.net/contest/250027#problem/I
题意: 现在有A,B两个国家,都有一个防御系统,每个但是防御系统有个时间,他能保证在有效时间内,将对方打过来的导弹打回去,AB分别有nm个导弹,并且知道他们的发射时间飞行时间,危害度,还知道B国家什么时候开启防御系统,问你A国家在最优的时间开启防御,能够收到的最小伤害是多少?
思路: 我们可以预处理出每个导弹对于A国家的有威胁的区间,只有这个区间全部包含在A国家的防御区间内,才可以保证对于A国家没有伤害,那么问题就转变成求一个特定的区间使得他完全包含的有威胁区间的危害度最大。 两个堆来维护就可以了。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e4+5;
struct node
{
ll st;
ll fei;
int val;
}a[N],b[N];
struct node1
{
ll l,r;
int val;
}dao[N];
ll TA,TB;
ll X;
ll tbl,tbr;
int n,m;
bool cmp1(node1 a,node1 b)
{
return a.l<b.l;
}
struct cmp2
{
bool operator ()(node1 &a ,node1 &b)
{
return a.l>b.l;
}
};
struct cmp3
{
bool operator ()(node1 &a,node1 &b)
{
return a.r>b.r;
}
};
int main()
{
while(scanf("%d %d",&TA,&TB)!=EOF)
{
scanf("%lld",&tbl);
tbr=tbl+TB;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%lld %lld %d",&a[i].st,&a[i].fei, &a[i].val);
}
for(int i=1;i<=m;i++){
scanf("%lld %lld %d",&b[i].st, &b[i].fei, &b[i].val);
}
int tot=0;
for(int i=1;i<=n;i++){
ll en=a[i].st+a[i].fei;
if(en<tbl||en>tbr) continue;
en+=a[i].fei;
dao[++tot].l=en; dao[tot].val=a[i].val;
ll len=tbr-dao[tot].l;
if(len<=0){
dao[tot].r=dao[tot].l;
}
ll len1=a[i].fei;
ll tim=len/len1;
if(tim%2==1) tim++;
dao[tot].r=dao[tot].l;
dao[tot].r+=tim*len1;
}
for(int i=1;i<=m;i++){
ll en=b[i].st+b[i].fei;
dao[++tot].l=en; dao[tot].val=b[i].val;
if(en+b[i].fei<tbl||en+b[i].fei>tbr){
dao[tot].r=en;
continue;
}
ll len=tbr-dao[tot].l;
if(len<=0){
dao[tot].r=dao[tot].l;
}
ll len1=b[i].fei;
ll tim=len/len1;
if(tim%2==1) tim++;
dao[tot].r=dao[tot].l;
dao[tot].r+=tim*len1;
}
priority_queue<node1,vector< node1> ,cmp2>q1;
priority_queue< node1 ,vector<node1 >,cmp3 >q2;
sort(dao+1,dao+tot+1,cmp1);
for(int i=1;i<=tot;i++){
q2.push(dao[i]);
}
/*
while(!q2.empty()){
cout<<q2.top().l<<" ** "<<q2.top().r<<" ** "<<q2.top().val<<endl;
q2.pop();
}
*/
ll L,R;
int sum=0;
int mx=0;
for(int i=1;i<=tot;i++){
L=dao[i].l;
R=dao[i].l+TA;
//cout<<"LLL "<<L<<" RR "<<R<<endl;
while(!q1.empty()&&q1.top().l<L){
sum-=q1.top().val;
q1.pop();
}
mx=max(sum,mx);
while(!q2.empty()&&q2.top().r<=R){
sum+=q2.top().val;
q1.push(q2.top());
q2.pop();
}
while(!q1.empty()&&q1.top().l<L){
sum-=q1.top().val;
q1.pop();
}
//cout<<"sum "<<sum<<"sz1 "<<q1.size()<<" sz2 "<<q2.size()<<endl;
mx=max(sum,mx);
}
int ss=0;
for(int i=1;i<=tot;i++){
ss+=dao[i].val;
}
ss-=mx;
printf("%d\n",ss);
}
return 0;
}
/*
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
*/