hihocoder 1391 树状数组

Posted Przz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hihocoder 1391 树状数组相关的知识,希望对你有一定的参考价值。

#1391 : Countries

时间限制:1000ms
单点时限:1000ms
内存限制:256MB

描述

There are two antagonistic countries, country A and country B. They are in a war, and keep launching missiles towards each other.

It is known that country A will launch N missiles. The i-th missile will be launched at time Tai. It flies uniformly and take time Taci from one country to the other. Its damage capability is Dai.

It is known that country B will launch M missiles. The i-th missile will be launched at time Tbi.

It flies uniformly and takes time Tbci from one country to the other. Its damage capability is Dbi.

Both of the countries can activate their own defending system.

The defending system of country A can last for time TA, while The defending system of country B can last for time TB.

When the defending system is activated, all missiles reaching the country will turn around and fly back at the same speed as they come.

At other time, the missiles reaching the country will do damages to the country.
(Note that the defending system is still considered active at the exact moment it fails)

Country B will activate its defending system at time X.

When is the best time for country A to activate its defending system? Please calculate the minimal damage country A will suffer.

输入

There are no more than 50 test cases.

For each test case:

The first line contains two integers TA and TB, indicating the lasting time of the defending system of two countries.

The second line contains one integer X, indicating the time that country B will active its defending system.

The third line contains two integers N and M, indicating the number of missiles country A and country B will launch.

Then N lines follow. Each line contains three integers Tai, Taci and Dai, indicating the launching time, flying time and damage capability of the i-th missiles country A launches.

Then M lines follow. Each line contains three integers Tbi, Tbci and Dbi, indicating the launching time, flying time and damage capability of the i-th missiles country B launches.

0 <= TA, TB, X, Tai, Tbi<= 100000000

1 <= Taci, Tbci <= 100000000

0 <= N, M <= 10000

1 <= Dai, Dbi <= 10000

输出

For each test case, output the minimal damage country A will suffer.

提示

In the first case, country A should active its defending system at time 3.

Time 1: the missile is launched by country A.

Time 2: the missile reaches country B, and country B actives its defending system, then the missile turns around.

Time 3: the missile reaches country A, and country A actives its defending system, then the missile turn around.

Time 4: the missile reaches country B and turns around.

Time 5: the missile reaches country A and turns around.

Time 6: the missile reaches country B, causes damages to country B.

 

样例输入
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

 

 

/*
hihocoder 1391 树状数组

problem:
A,B两个敌对国分别有1W个导弹,每个导弹有各自的发射时间、飞行时间、造成伤害。两国各有一个防御系统,
且分别有各自的持续时间(相当于防御一个时间区间?),开启防御系统时,所有到达该国的导弹按原速度反向。
已知B国在X时间点开启防御系统,问A国最少会受多少的伤害。(以上数值伤害1e4,其余1e8)

solve:
昨天比赛心态爆炸.......Orz
因为导弹可以在两个国家之间互相弹来弹去. 我们可以计算出这个导弹最早攻击到A的时间l和最晚到达A的时间r(假设A防御时间无限)
如果开启防御后无法覆盖[l,r]那么这个导弹总会攻击到A.
然后问题就成了已知很多个区间的价值,完全覆盖是能够得到价值.求长度为len的区间最多能得到多少价值.
所以可以通过树状数组来解决了.
如果从小到大枚举r,找出以当前点为右端点能覆盖多少的值.
那么每次就要将区间的值赋予l,因为只有左端点小于等于l时才覆盖这个区间.

//比赛时少了个判断, 而且求k值错了...卒

hhh-2016-09-25 15:22:55
*/
#pragma comment(linker,"/STACK:124000000,124000000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#include <math.h>
#define lson  i<<1
#define rson  i<<1|1
#define ll long long
#define clr(a,b) memset(a,b,sizeof(a))
#define key_val ch[ch[root][1]][0]
using namespace std;
#define mod 1004535809LL

const int maxn = 5e5;
int n,m,k;
ll ta,tb,x;
ll u,v,w,y,tot;

map<ll,ll> mp;
ll sum;
ll mis[100010];
struct node
{
    ll l,r;
    ll w;
} pnode[maxn * 10];

bool cmp(node a,node b)
{
    return a.r< b.r;
}

ll s[maxn*5];
int lowbit(int x)
{
    return x&(-x);
}

void add(int pos,ll val)
{
    if(pos <= 0)
        return ;
    while(pos <= tot)
    {
        s[pos] += val;
        pos += lowbit(pos);
    }
}

ll cal(int pos)
{
    ll cnt = 0;
    if(pos <= 0)
        return 0;
    while(pos > 0)
    {
        cnt += s[pos];
        pos -= lowbit(pos);
    }
    return cnt;
}

int cnt ;
int main()
{
    while(scanf("%lld %lld",&ta,&tb)!=EOF)
    {
        mp.clear();
        sum=0;
        tot=1;
        cnt=1;
        scanf("%lld",&x);
        y=x+tb;
        memset(s,0,sizeof(s));
        scanf("%d %d",&n,&m);
        for(int i=0; i<n; i++)
        {
            scanf("%lld %lld %lld",&u,&v,&w);
            if(u+v>y||u+v<x) continue;
            sum+=w;

            k = (y - u) / v;
            if(k % 2LL == 0LL)
                k-=3LL;
            while(k*v + u <= y) k +=2LL;

            //k=3;
            //while(u+k*v<=y) k+=2;
            pnode[cnt].l = u+2LL*v;
            pnode[cnt].r = u+(k-1LL)*v;
//            cout << pnode[cnt].l << " " <<pnode[cnt].r <<endl;
            mis[tot ++] = u+2LL*v, mis[tot++] = u+(k-1LL)*v;
            pnode[cnt++].w= w;
        }
        for(int i=0; i<m; i++)
        {
            scanf("%lld %lld %lld",&u,&v,&w);
            sum+=w;

            k = (y - u) / v;
            if(k % 2LL == 1LL)
                k-=3LL;
            while(u+k*v<=y) k +=2LL;

            pnode[cnt].l = u+v;
//            if(u + 2*v > y || u+ 2*v < x)
//                pnode[cnt].r = pnode[cnt].l;
//            else{
            pnode[cnt].r =u+(k-1LL)*v;
            mis[tot++] = u+(k-1LL)*v;
//            }
            mis[tot ++] = u+v;
            pnode[cnt++].w= w;
        }

        sort(mis+1,mis+tot);
        int t = unique(mis+1,mis+tot) - mis;
        sort(pnode+1,pnode + cnt,cmp);
        for(int i= 1; i < t; i++)
        {
            mp[mis[i]] = i;
        }

        int cur = 1;
        ll Max = 0;

        for(int i = 1; i < t; i++)
        {
            ll ed = mis[i];
            ll from = ed - ta;

            while(mp[pnode[cur].r] == i && cur < cnt)
            {
                add(mp[pnode[cur].l],pnode[cur].w);
                cur ++;
            }
            int pos = lower_bound(mis+1,mis+t,from) - mis;
            Max =max(Max,cal(i) - cal(pos-1));
        }
//        cout <<Max <<endl;
        printf("%lld\n",sum - Max);
    }
    return 0;
}

  

以上是关于hihocoder 1391 树状数组的主要内容,如果未能解决你的问题,请参考以下文章

HihoCoder1336 Matrix Sum(树状数组)

hihoCoder 1391 Countries 预处理+排序+堆 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛)

HihoCoder 1488 : 排队接水(莫队+树状数组)

Hihocoder 1167 高等理论计算机科学 (树链的交,线段树或树状数组维护区间和)

hihocoder第233周

hihoCoder 数组重排