• ZZNU 2098 Drink coffee(差分+树状数组)


    题目链接:http://acm.hi-54.com/problem.php?pid=2098

    2098 : Drink coffee

    时间限制:1 Sec 内存限制:256 MiB
    提交:32 答案正确:9

     

    题目描述

    为了在上课时保持清醒,凯伦需要一些咖啡。咖啡爱好者凯伦想知道最佳的温度来冲煮完美的咖啡。因此,她花了一些时间阅读几本食谱,其中包括广受好评的咖啡的艺术

    她知道有n个食谱,其中第i个食谱建议应当在liri度之间冲煮以达到最佳的味道。凯伦认为如果至少k个食谱推荐某个温度,那么那个温度是可以接受的。

    凯伦的性格比较多变,因此她会问q个问题,对于每一个问题,她会给出一个温度区间[a,b],你要告诉她有多少可接受的整数温度在这个范围内。

    输入

    第一行输入包含三个整数,nk1kn200000)和q1q200000),如题中所描述。

    接下来n行描述每一个食谱,具体来说,其中的第i行包含两个整数liri1liri200000),描述第i个食谱建议咖啡在liri度之间进行冲煮(包括端值)。

    接下来q行为q个询问。这些行中的每一行都包含ab,(1ab200000),表示她想知道ab度之间的可接受的整数温度的数量,包括ab

    输出

    对于每个询问,输出一个答案。

    样例输入

    复制
    3 2 4
    91 94
    92 97
    97 99
    92 94
    93 97
    95 96
    90 100

    样例输出

    复制
    3
    3
    0
    4

    题意就是先给几个区间,每次都对区间中所有元素累加一次,
    最后询问Q次,问在某个区间内次数大于k这样的数字有几个。

    就是个裸的树状数组啊,可是以前刷树状数组的时候没写过区间更新区间查询的题,太久没写树状数组,突然手生,比赛时候没写出来。

    然后这道题,用到了差分的思想,每次对区间开始和结束进行差分标记(等等,好像写过类似的,想起来了当时写HDU1556
    还写了这个博客)no wonder感觉在哪见过类似思想。

    赛后补了下区间修改,看了这个博客:https://blog.csdn.net/noiau/article/details/76531671
    我应该会了,吧?


    哦,对了本题AC代码:
    #include<cstdio>
    #include<iostream>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include<cmath>
    #define ll long long
    using namespace std;
    const int maxn=2e5+10;
    int Tree[maxn],n,ans[maxn],sum[maxn];
    inline int lowbit(int x)
    {
        return (x&-x);
    }
    void add(int x,int val)
    {
        for(int i=x;i<maxn;i+=lowbit(i))
            Tree[i]+=val;
    }
    int get(int x,int y)
    {
        int sum1=0,sum2=0;
        for(int i=x;i>0;i-=lowbit(i))
            sum1+=Tree[i];
        for(int i=y;i>0;i-=lowbit(i))
            sum2+=Tree[i];
        return sum2-sum1;
    }
    int main()
    {
        int n,k,q,x,y;
        while(~scanf("%d%d%d",&n,&k,&q))
        {
            memset(Tree,0,sizeof(Tree));
            memset(ans,0,sizeof(ans));
            memset(sum,0,sizeof(sum));
            for(int i=0;i<n;i++)
            {
                scanf("%d%d",&x,&y);
                ans[x]++; ans[y+1]--;
            }
            for(int i=1;i<=maxn;i++)
            {
                sum[i]=sum[i-1]+ans[i];
                if(sum[i]>=k)   add(i,1);
            }
            for(int i=1;i<=q;i++)
            {
                scanf("%d%d",&x,&y);
                printf("%d
    ",get(x-1,y));
            }
        }
        return 0;
    }
    
    
    
    
    
    





  • 相关阅读:
    设计模式(九)外观模式Facade(结构型)
    设计模式(八)装饰器模式Decorator(结构型)
    Linux新手生存笔记[1]——Linux目录结构及说明
    设计模式(三)建造者模式Builder(创建型)
    设计模式(七)组合模式Composite(结构型)
    Linux新手生存笔记[0]——写在前面
    给出两个数m和n,求它们的最大公因子,即能够同时整出m和n的最大正整数
    Linux新手生存笔记[2]——vim训练稿
    Linux新手生存笔记[10]——shell脚本基础3函数及常用命令
    设计模式 ( 十二 ) 职责链模式(Chain of Responsibility)(对象行为
  • 原文地址:https://www.cnblogs.com/weimeiyuer/p/9087796.html
Copyright © 2020-2023  润新知