免费送气球

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

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\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
6
1 5 1
1 6 3
2 2 5
2 4 8
1 2 2
2 4 8
 
Sample Output
4
11
9
 
题意: 中文题。
解析:离散化之后,建立权值线段树。维护一个ans数组用于区间权值求和,维护一个sum数组用于区间个数求和 和 查询出第first大和second大离散化之后得下标x,y
 
answer = queryans(1,y-1) - queryans(1,x-1) + (second-querysum(1,y-1))*v[ y-1 ] - (first-querysum(1,x-1))*v[ x-1 ]
 
AC代码
  1. #include <bits/stdc++.h>
  2. #define pb push_back
  3. #define mp make_pair
  4. #define fi first
  5. #define se second
  6. #define all(a) (a).begin(), (a).end()
  7. #define fillchar(a, x) memset(a, x, sizeof(a))
  8. #define huan printf("\n")
  9. #define debug(a,b) cout<<a<<" "<<b<<" "<<endl
  10. #define ffread(a) fastIO::read(a)
  11. using namespace std;
  12. typedef long long ll;
  13. const int maxn = 1e5+;
  14. const int inf = 0x3f3f3f3f;
  15. const ll mod = ;
  16. const double epx = 1e-;
  17. const double pi = acos(-1.0);
  18. //head-----------------------------------------------------------------
  19. ll sum[maxn*],ans[maxn*];
  20. void PushUp(int rt)
  21. {
  22. sum[rt]=sum[rt<<]+sum[rt<<|];
  23. ans[rt]=(ans[rt<<]+ans[rt<<|])%mod;
  24. }
  25. void update(int x,ll val,ll vall,int l,int r,int rt)
  26. {
  27. if(l==x&&r==x)
  28. {
  29. sum[rt]+=vall;
  30. ans[rt]=(ans[rt]+val)%mod;
  31. return;
  32. }
  33. int mid=(l+r)>>;
  34. if(x<=mid)
  35. update(x,val,vall,l,mid,rt<<);
  36. else
  37. update(x,val,vall,mid+,r,rt<<|);
  38. PushUp(rt);
  39. }
  40. ll query1(int L,int R,int l,int r,int rt)
  41. {
  42. if(R<L)
  43. return ;
  44. if(L<=l&&R>=r)
  45. {
  46. return sum[rt];
  47. }
  48. int mid=(l+r)>>;
  49. ll anss=;
  50. if(L<=mid)
  51. anss+=query1(L,R,l,mid,rt<<);
  52. if(R>mid)
  53. anss+=query1(L,R,mid+,r,rt<<|);
  54. return anss;
  55. }
  56. int query2(ll x,int l,int r,int rt)
  57. {
  58. if(l==r)
  59. {
  60. return l;
  61. }
  62. int mid=(l+r)>>;
  63. if(sum[rt<<]>=x)
  64. return query2(x,l,mid,rt<<);
  65. else
  66. return query2(x-sum[rt<<],mid+,r,rt<<|);
  67. }
  68. ll query3(int L,int R,int l,int r,int rt)
  69. {
  70. if(R<L)
  71. return ;
  72. if(L<=l&&R>=r)
  73. {
  74. return ans[rt];
  75. }
  76. int mid=(l+r)>>;
  77. ll anss=;
  78. if(L<=mid)
  79. anss=(anss+query3(L,R,l,mid,rt<<))%mod;
  80. if(R>mid)
  81. anss=(anss+query3(L,R,mid+,r,rt<<|))%mod;
  82. return anss;
  83. }
  84. struct query
  85. {
  86. ll op,x,y;
  87. }q[maxn];
  88. vector<ll> v;
  89. int getid(ll x)
  90. {
  91. return lower_bound(all(v),x)-v.begin()+;
  92. }
  93. int main()
  94. {
  95. int n;
  96. scanf("%d",&n);
  97. {
  98. for(int i=;i<n;i++)
  99. {
  100. scanf("%lld%lld%lld",&q[i].op,&q[i].x,&q[i].y);
  101. v.pb(q[i].y);
  102. }
  103. sort(all(v));
  104. v.erase(unique(all(v)),v.end());
  105. int sizen=v.size();
  106. for(int i=;i<n;i++)
  107. {
  108. if(q[i].op==)
  109. {
  110. update(getid(q[i].y),(q[i].y*q[i].x)%mod,q[i].x,,sizen,);
  111. }
  112. else
  113. {
  114. int valx=query2(q[i].x,,sizen,);
  115. int valy=query2(q[i].y,,sizen,);
  116. if(valx==valy)
  117. {
  118. ll ret = ((q[i].y-q[i].x+)%mod*v[valx-])%mod;
  119. printf("%lld\n",ret);
  120. }
  121. else
  122. {
  123. ll numx=query1(,valx-,,sizen,);
  124. ll numy=query1(,valy-,,sizen,);
  125. ll ret=(query3(,valy-,,sizen,)-query3(,valx-,,sizen,)+mod)%mod;
  126. ret=(ret-((q[i].x-numx-)%mod*v[valx-])%mod+mod)%mod;
  127. ret=(ret+((q[i].y-numy)%mod)*v[valy-]%mod)%mod;
  128. printf("%lld\n",ret);
  129. }
  130. }
  131. }
  132. }
  133. }

zyb的面试

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

Problem Description
今天zyb参加一场面试,面试官听说zyb是ACMer之后立马抛出了一道算法题给zyb:
有一个序列,是1到n的一种排列,排列的顺序是字典序小的在前,那么第k个数字是什么?
例如n=15,k=7, 排列顺序为1, 10, 11, 12, 13, 14, 15, 2, 3, 4, 5, 6, 7, 8, 9;那么第7个数字就是15.
那么,如果你处在zyb的场景下,你能解决这个问题吗?
 
Input
T组样例(T<=100)
两个整数n和k(1<=n<=1e6,1<=k<=n),n和k代表的含义如上文
 
Output
输出1-n之中字典序第k小的数字
 
Sample Input
1
15 7
 
Sample Output
15
 
题意:序列1-n 字典序排序之后 第k个数是多少。
解析:肯定不能字符串排序,铁超时。。。容易想到先计算出 1-9开头的数分别有多少 判断k在哪个区间 从而确定了第一位数 在确定的数字基础上在进行同样的操作 0-9...
所以 写一个函数进行计算 直到k=0。
 
AC代码
  1. #include <bits/stdc++.h>
  2. #define pb push_back
  3. #define mp make_pair
  4. #define fi first
  5. #define se second
  6. #define all(a) (a).begin(), (a).end()
  7. #define fillchar(a, x) memset(a, x, sizeof(a))
  8. #define huan printf("\n")
  9. #define debug(a,b) cout<<a<<" "<<b<<" "<<endl
  10. #define ffread(a) fastIO::read(a)
  11. using namespace std;
  12. typedef long long ll;
  13. const int maxn = 1e2+;
  14. const int inf = 0x3f3f3f3f;
  15. const int mod = ;
  16. const double epx = 1e-;
  17. const double pi = acos(-1.0);
  18. //head-----------------------------------------------------------------
  19. vector<int> ans; //已确定的数字
  20. int getnum(int x,int y)
  21. {
  22. int res=,ji=,now=;
  23. for(int i=ans.size()-;i>=;i--)
  24. {
  25. now+=ans[i]*ji;
  26. ji*=;
  27. }
  28. for(int i=;i<=1e6;i*=) //位数
  29. {
  30. int temp=min((x++now)*i,y+);
  31. if(temp>=(now+x)*i)
  32. res+=temp-(now+x)*i;
  33. if(temp==y+)
  34. break;
  35. }
  36. return res;
  37. }
  38. int main()
  39. {
  40. int t,n,m;
  41. scanf("%d",&t);
  42. while(t--)
  43. {
  44. ans.clear();
  45. scanf("%d%d",&n,&m);
  46. while(m!=)
  47. {
  48. int sum=;
  49. for(int i=;i<;i++)
  50. {
  51. if(ans.size()==&&i==)
  52. continue;
  53. int temp=getnum(i,n);
  54. if(sum+temp>=m)
  55. {
  56. m-=sum;
  57. ans.pb(i);
  58. m--;
  59. break;
  60. }
  61. sum+=temp;
  62. }
  63. }
  64. for(int i=;i<ans.size();i++)
  65. cout<<ans[i];
  66. cout<<endl;
  67. }
  68. }

HDU 6464 权值线段树 && HDU 6468 思维题的更多相关文章

  1. HDU 6464 /// 权值线段树

    题目大意: 共Q次操作 操作有两种 操作一 在序列尾部加入f[i]个s[i] 操作二 查询序列第f[i]小到第s[i]小之间的总和 离线操作 把序列内的值离散化 然后利用离散化后的值 在线段树上对应权 ...

  2. 区间第k大问题 权值线段树 hdu 5249

    先说下权值线段树的概念吧 权值平均树 就是指区间维护值为这个区间内点出现次数和的线段树 用这个加权线段树 解决第k大问题就很方便了 int query(int l,int r,int rt,int k ...

  3. HDU 5249:KPI(权值线段树)

    KPI Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Desc ...

  4. HDU 6464 免费送气球 【权值线段树】(广东工业大学第十四届程序设计竞赛)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6464 免费送气球 Time Limit: 2000/1000 MS (Java/Others)    M ...

  5. 2019年CCPC网络赛 HDU 6703 array【权值线段树】

    题目大意:给出一个n个元素的数组A,A中所有元素都是不重复的[1,n].有两种操作:1.将pos位置的元素+1e72.查询不属于[1,r]中的最小的>=k的值.强制在线. 题解因为数组中的值唯一 ...

  6. R - Weak Pair HDU - 5877 离散化+权值线段树+dfs序 区间种类数

    R - Weak Pair HDU - 5877 离散化+权值线段树 这个题目的初步想法,首先用dfs序建一颗树,然后判断对于每一个节点进行遍历,判断他的子节点和他相乘是不是小于等于k, 这么暴力的算 ...

  7. HDU - 2665 Kth number 主席树/可持久化权值线段树

    题意 给一个数列,一些询问,问$[l,r]$中第$K$大的元素是哪一个 题解: 写法很多,主席树是最常用的一种之一 除此之外有:划分树,莫队分块,平衡树等 主席树的定义其实挺模糊, 一般认为就是可持久 ...

  8. HDU - 5592 ZYB's Premutation (权值线段树)

    题意:给出序列前k项中的逆序对数,构造出这个序列. 分析:使用权值线段树来确定序列元素. 逆序对的数量肯定是递增的,从最后一个元素开始逆向统计,则\(a[i] - a[i-1]\)即位置i之前比位置i ...

  9. hdu 5592 ZYB's Premutation (权值线段树)

    最近在线段树的世界里遨游,什么都能用线段树做,这不又一道权值线段树了么. ZYB's Premutation Time Limit: 2000/1000 MS (Java/Others)    Mem ...

随机推荐

  1. list 方法总结整理

    #!/usr/bin/env python #Python 3.7.0 列表常用方法 __author__ = "lrtao2010" #创建列表 # a = [] # b = [ ...

  2. 使用nohup+& 踩到的坑

    首先分清楚nohup与&: &是指在后台运行一般在执行命令后,都会显式的在前台执行,当Ctrl+C后进程回宕掉,但是 在命令后加&,即使Ctrl+C,程序还在进行,但是,当关闭 ...

  3. debian 7 安装vagrant

    下载 vagrant_1.4.3_x86_64.deb: $ wget http://966b.http.dal05.cdn.softlayer.net/data-production/2f0b88e ...

  4. Nginx与Lua的开发

    1. Lua基础语法 安装lua hello world 也可以编写lua脚本 运行脚本 lua注释 变量 局部变量的话前面加个local 循环 if语句 2. Nginx与Lua开发环境 https ...

  5. loj2021 「HNOI2017」大佬

    there #include <algorithm> #include <iostream> #include <cstring> #include <cst ...

  6. 图解spring事务管理的实现

  7. 用qemu+gdb tcp server+CDT调试linux内核启动-起步

    用qemu+gdb tcp server+CDT调试linux内核启动-起步 说明: 环境信息与 用virtualbox+模拟串口+CDT调试linux内核 TCP IP协议栈-起步 提到的一样,并且 ...

  8. webdriver高级应用- 在ajax方式产生的浮动框中,单击选择包含某个关键字的选项

    Ajax简介: Ajax:局部刷新,原理上也是一个js,js调用服务器的远程接口刷新局部页面数据. Ajax = 异步 JavaScript 和 XML(标准通用标记语言的子集). Ajax 是一种用 ...

  9. ASP.NET MVC下使用SWFUpload完成剪切头像功能

    首先介绍SWFUpload组件 SWFUpload是一个客户端文件上传工具,最初由Vinterwebb.se开发,它通过整合Flash与JavaScript技术 为WEB开发者提供了一个具有丰富功能继 ...

  10. Python 调用multiprocessing模块下面的Process类方法(实现服务器、客户端并发)-UDP协议

    #基于UDP协议的multiprocessing自定义通信 服务端: from multiprocessing import Process import socket def task(server ...