• HDU 6464.免费送气球-动态开点-权值线段树(序列中第first小至第second小的数值之和)(感觉就是只有一个状态的主席树) (“字节跳动-文远知行杯”广东工业大学第十四届程序设计竞赛)


    免费送气球

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 581    Accepted Submission(s): 130


    Problem Description
    又到了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 ", 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
    6 1 5 1 1 6 3 2 2 5 2 4 8 1 2 2 2 4 8
     
    Sample Output
    4 11 9
     
    Source
     
     
    动态开点就相当于离散化了。
     
    代码:
     1 //6464-权值线段树
     2 #include<bits/stdc++.h>
     3 using namespace std;
     4 typedef long long ll;
     5 const int maxn=1e5+10;
     6 const int inf=0x3f3f3f3f;
     7 const int mod=1e9+7;
     8 #define lson l,m
     9 #define rson m+1,r
    10 
    11 ll sum[maxn*40],val[maxn*40];
    12 int ls[maxn*40],rs[maxn*40];
    13 int cnt;
    14 
    15 void update(int &rt,int l,int r,ll k,ll num)
    16 {
    17     if(!rt) rt=++cnt;
    18     sum[rt]+=k;
    19     cout<<rt<<" "<<sum[rt]<<endl;
    20     val[rt]+=(ll)k*num;
    21     val[rt]%=mod;
    22     if(l==r){
    23         return ;
    24     }
    25 
    26     int m=(l+r)>>1;
    27     if(num<=m) update(ls[rt],lson,k,num);
    28     else update(rs[rt],rson,k,num);
    29 }
    30 
    31 ll query(int rt,int l,int r,ll k)
    32 {
    33     if(l==r){
    34         return 1ll*k*l%mod;
    35     }
    36 
    37     int m=(l+r)>>1;
    38     ll ans=0;
    39     if(k>sum[ls[rt]]) ans=(val[ls[rt]]+query(rs[rt],rson,k-sum[ls[rt]]))%mod;
    40     else ans=query(ls[rt],lson,k);
    41     return ans%mod;
    42 }
    43 
    44 int main()
    45 {
    46     int q,rt=0;
    47     scanf("%d",&q);
    48     while(q--){
    49         int op;
    50         ll l,r;
    51         scanf("%d%lld%lld",&op,&l,&r);
    52         if(op==1){
    53             update(rt,0,1e9,l,r);
    54         }
    55         else{
    56             ll ans=(query(rt,0,1e9,r)-query(rt,0,1e9,l-1)%mod+mod)%mod;
    57             printf("%lld
    ",ans);
    58         }
    59     }
    60     return 0;
    61 }
     
  • 相关阅读:
    POJ 2159 Ancient Cipher 难度:0
    POJ 3299 Humidex 难度:0
    POJ 1503 Integer Inquiry 大数 难度:0
    POJ 2262 Goldbach's Conjecture 数学常识 难度:0
    POJ 1083 Moving Tables 思路 难度:0
    PAT 甲级 1126 Eulerian Path
    Java 大数运算
    PAT 甲级 1010 Radix
    PAT 甲级 1137 Final Grading
    PAT 甲级 1064 Complete Binary Search Tree
  • 原文地址:https://www.cnblogs.com/ZERO-/p/10580613.html
Copyright © 2020-2023  润新知