您的位置:首页 > 理论基础 > 计算机网络

hihocoder 1391 : Countries 北京网络赛(树状数组+离散化)

2016-09-27 23:15 337 查看
题目:http://www.hihocoder.com/problemset/problem/1391?sid=895605

官方题解:



分析:

我们可以预处理出导弹到达A的每个时间段,这样问题就转化成了求[x,x+TA]覆盖最大的时间段相应的代价和,这个范围内的导弹是可以防御住的,那么剩下的就是无法防御的。

所以用树状数组求解,时间的数据范围有点大,离散化一下即可。

代码:

using namespace std;
typedef long long ll;
const int N=1e5+9;

ll c
;
int lowbit(int x) {
return x&(-x);
}
ll getsum(int x) {
ll sum=0;
for(int i=x; i>0; i-=lowbit(i))sum+=c[i];
return sum;
}
void add(int x,ll v) {
for(int i=x; i<N; i+=lowbit(i))c[i]+=v;
}
struct Item {
ll l,r,v;
bool operator < (const Item& rhs)const {
return r<rhs.r;
}
} a
;
ll b
;
map<ll,int>id;
int main() {
//freopen("f.txt","r",stdin);
ll Ta,Tb,Sb,s,t,v;
int n,m;
while(~scanf("%lld%lld",&Ta,&Tb)) {
memset(c,0,sizeof(c));
id.clear();
scanf("%lld",&Sb);
scanf("%d%d",&n,&m);
ll Eb=Tb+Sb,sum=0;
int cnt=0;
for(int i=1; i<=n; i++) {
scanf("%lld%lld%lld",&s,&t,&v);
if(s+t>=Sb&&s+t<=Eb) {
a[cnt].l=s+2*t;
a[cnt].r=s+2*t+(Eb-s-t)/(2*t)*2*t;
a[cnt].v=v;
cnt++;
sum+=v;
}
}
for(int i=1; i<=m; i++) {
scanf("%lld%lld%lld",&s,&t,&v);
a[cnt].l=s+t;
a[cnt].v=v;
sum+=v;
if(s+2*t<Sb||s+2*t>Eb)a[cnt].r=a[cnt].l;
else a[cnt].r=s+3*t+(Eb-s-2*t)/(2*t)*2*t;
cnt++;
}
int tot=0;
for(int i=0; i<cnt; i++) {
b[tot++]=a[i].l;
b[tot++]=a[i].r;
b[tot++]=a[i].r-Ta;
}
sort(b,b+tot);
tot=unique(b,b+tot)-b;

for(int i=0; i<tot; i++)id[b[i]]=i+1;
sort(a,a+cnt);
ll ans=0;
for(int i=0; i<cnt; i++) {
add(id[a[i].l],a[i].v);
ans=max(ans,getsum(id[a[i].r])-getsum(id[a[i].r-Ta]-1));
}
printf("%lld\n",sum-ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: