现在的位置: 首页 > 综合 > 正文

hdu 4970 Killing Monsters Multi-University Training Contest 9

2018年01月14日 ⁄ 综合 ⁄ 共 1180字 ⁄ 字号 评论关闭

再一次被智商题碾压,正解用的trick很巧妙,因为区间有可能是交叉重叠的,所以在stone[l]处+d,stone[r+1]处-d,从左到右扫描,如果某一点还停留在区间内,则会类加上stone[l],如果在区间外,扫描就穿过了区间,+d,-d没有影响。所以从头到尾扫描得出的就是经过某一点时减少的value。然后从该点往后遍历就得到了x to N减少的value,但是因为要求出所有点,从后往前遍历就是O(N)。

#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<stdlib.h>
#include<vector>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<queue>
#include <ctype.h>
#include<map>
#include<time.h>
using namespace std;
//hdu 4970

const int maxn=100010;
long long  stone[maxn];
long long  sum[maxn];
long long H[maxn];
int X[maxn];
int K;
int N;
int M;
int main()
{
    freopen("input.txt","r",stdin);
   //  freopen("data.txt","r",stdin);
    // freopen("out1.txt","w",stdout);
    while(true)
    {
        scanf("%d",&N);
        if(N==0) break;
        scanf("%d",&M);
        memset(stone,0,sizeof(stone));
        memset(sum,0,sizeof(sum));
        int l,r=0;
        long long d=0;
        int ans=0;
        for(int i=0;i<M;i++)
        {
            scanf("%d %d %I64d",&l,&r,&d);
            stone[l]+=d;//注意不能直接赋值,可能有区间重合,并且stone[i]最大值为10W*1000,所以要用long long 存
            stone[r+1]-=d;
        }
        scanf("%d",&K);
        for(int i=0;i<K;i++)
        {
            scanf("%I64d %d",&H[i],&X[i]);
        }
        sum[0]=stone[0];
        for(int i=1;i<N;i++)
        {
            sum[i]+=sum[i-1]+stone[i];
        }
        for(int i=N-1;i>=0;i--)
        {
            sum[i]+=sum[i+1];
        }
        for(int i=0;i<K;i++)
        {
            if(H[i]>sum[X[i]]) ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
}



抱歉!评论已关闭.