博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU - 6464 免费送气球(线段树二分)
阅读量:5158 次
发布时间:2019-06-13

本文共 2717 字,大约阅读时间需要 9 分钟。

题意:
又到了GDUT一年一度的程序设计竞赛校赛的时间啦。同学们只要参加校赛,并且每解出一道题目就可以免费获得由ACM协会和集训队送出的气球一个。听到这个消息,JMC也想参加免费拿气球。可是,由于JMC太菜了而被禁止参赛,于是他找到你想让你帮忙参加比赛,可以通过执行下面的C++程序解决问题后获得气球并送给他。JMC保证了下面的程序一定能获得正确的结果。 
void solve(int Q, int type[], long long first[], long long second[]) { 
    vector<long long> vec; 
    for (int i = 0; i < Q; ++i) { 
        if (type[i] == 1) { 
            long long k = first[i], val = second[i]; 
            while (k--) { 
                vec.push_back(val); 
            } 
        } 
        else if (type[i] == 2) { 
            sort(vec.begin(), vec.end()); 
            long long l = first[i] - 1, r = second[i], res = 0; 
            while (l < r) { 
                res = (res + vec[l++]) % 1000000007; 
            } 
            printf("%lld\n", res); 
        } 
    } 
为防止你被JMC的代码搞到头晕目眩,JMC特意给出了问题的文字描述。已知一开始有一个空序列,接下来有Q次操作,每次操作给出type、first和second三个值。当type为1时,意味着该操作属于第一种操作:往序列尾部添加first个second数。当type为2时,意味着该操作属于第二种操作:查询序列中第first小至第second小的数值之和(一共有(second - first + 1)个数被累加),并将结果对1000000007取模后输出。

Input

单组数据 

第一行一个Q(1 <= Q <= 1e5),代表Q次操作。 
接下来有Q行,每行包含三个整数type、first和second;其中1 <= type <= 2。当type等于1时,0 <= first,second < 1e9。当type等于2时,1 <= first <= second,且first和second均不大于目前已添加进序列的数的数量。Output对于每次操作二,将结果对1000000007取模后输出。Sample Input

61 5 11 6 32 2 52 4 81 2 22 4 8

Sample Output

4119

首先了解离散化的概念:

数据的离散化

有些数据本身很大, 自身无法作为数组的下标保存对应的属性。如果这时只是需要这堆数据的相对属性, 那么可以对其进行离散化处理。当数据只与它们之间的相对大小有关,而与具体是多少无关时,可以进行离散化。
例如:
91054与52143的逆序对个数相同。
设有4个数:
1234567、123456789、12345678、123456
排序:123456<1234567<12345678<123456789
=>1<2<3<4
那么这4个数可以表示成:2、4、3、1

题解:首先将所有将要添加的数离散化,然后建立两颗线段树,分别维护区间内数的数量和区间和。对于操 作一,根据离散化后的值在线段树对应位置添加 k 个 val,并维护线段树每一个节点所代表区间的和。 对于操作二,首先将问题转化成两个前 k 小之和的查询,具体做法:传入参数 k 搜索线段树,先递归 检查左子区间的数的数量,如果小于当前 k,再传入当前 k-'左子区间的数的数量'作为更新后的参数 k 递归搜索右子区间;递归搜索时,应将满足数量条件(当前区间的数的数量小于等于 k)等于的区间和 累加并返回作为答案。 

参考博客:

#include 
#include
#include
#include
#include
using namespace std;typedef long long ll;#define mod 1000000007#define MAXN 100005#define N 100005struct query1{ ll t; ll f,s; query1(ll a,ll b,ll c){ t=a; f=b; s=c; } query1(){}}que[100005];map
mp;ll cnt=0;ll sorted[100005];ll num[MAXN<<2];ll sum[MAXN<<2];void pushup(ll rt){ num[rt]=(num[rt<<1]+num[rt<<1|1]); sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%mod;}void update(ll P,ll C,ll l,ll r,ll rt){ if(l==r){ num[rt]=(num[rt]+C); sum[rt]=(sum[rt]+mp[P]*C%mod)%mod; return; } ll m=(l+r)/2; if(P<=m) update(P,C,l,m,rt<<1); else update(P,C,m+1,r,rt<<1|1); pushup(rt);}ll query(ll K,ll l,ll r,ll rt){ if(K==0) return 0; if(l==r){ return K*mp[l]%mod; } ll m=(l+r)/2; if(num[rt<<1]>=K){ return query(K,l,m,rt<<1)%mod; } else{ return (sum[rt<<1]+query(K-num[rt<<1],m+1,r,rt<<1|1))%mod; }}int main(){ ll Q; scanf("%I64d",&Q); ll fir,sec; ll t; for(ll i=0;i
pm; int cc=1; for(int i=0;i

转载于:https://www.cnblogs.com/LJHAHA/p/10860738.html

你可能感兴趣的文章
spring IOC装配Bean(注解方式)
查看>>
[面试算法题]有序列表删除节点-leetcode学习之旅(4)
查看>>
kubernetes_book
查看>>
侧边栏广告和回到顶部
查看>>
https://blog.csdn.net/u012106306/article/details/80760744
查看>>
海上孤独的帆
查看>>
处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“Manag
查看>>
01: socket模块
查看>>
mysql触发器
查看>>
淌淌淌
查看>>
win10每次开机都显示“你的硬件设置已更改,请重启电脑……”的解决办法
查看>>
C++有关 const & 内敛 & 友元&静态成员那些事
查看>>
函数积累
查看>>
Swift 入门之简单语法(六)
查看>>
〖Python〗-- IO多路复用
查看>>
栈(括号匹配)
查看>>
Java学习 · 初识 面向对象深入一
查看>>
源代码如何管理
查看>>
vue怎么将一个组件引入另一个组件?
查看>>
bzoj1040: [ZJOI2008]骑士
查看>>