加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

3110: [Zjoi2013]K大数查询

发布时间:2020-12-14 04:54:01 所属栏目:大数据 来源:网络整理
导读:题目大意,带该段的区间第k大。 注意,一个位置上可以有多个数的,更改操作是增加新数,而不是覆盖。 备用知识:标记永久化点击打开链接(不用的话应该也可以,但空间会大) 然后就上权值线段树套区间线段树。 不修改的区间第k小是例题(类似二分),树套树

题目大意,带该段的区间第k大。

注意,一个位置上可以有多个数的,更改操作是增加新数,而不是覆盖。

备用知识:标记永久化点击打开链接(不用的话应该也可以,但空间会大)

然后就上权值线段树套区间线段树。

不修改的区间第k小是例题(类似二分),树套树可以解决修改的问题。

我们可以c+n+1转正,然后把求区间第k大变成(len-k+1)小。

答案再减回来就行了。

要用long long

code:

[cpp]? view plain ?copy
  1. #include<cstdio>??
  2. #include<cstdlib>??
  3. #include<cstring>??
  4. #include<iostream>??
  5. #define?LL?long?long??
  6. using?namespace?std;??
  7. int?n,m,N;??
  8. struct?node{??
  9. ????int?lc,rc;??
  10. ????LL?c,u;??
  11. }tr[20200010];int?trlen=0,root[200010];??
  12. void?update(int?&x,int?l,87); font-weight:bold; background-color:inherit">int?r,87); font-weight:bold; background-color:inherit">int?fl,87); font-weight:bold; background-color:inherit">int?fr,LL?c)??
  13. {??
  14. ????if(!x)?x=++trlen;??
  15. ????if(l==fl&&r==fr){tr[x].u+=c;tr[x].c+=c*(r-l+1);return;}??
  16. ????int?mid=(l+r)/2;??
  17. if(fr<=mid)?update(tr[x].lc,l,mid,fl,fr,c);??
  18. else?if(fl>mid)?update(tr[x].rc,mid+1,r,c);??
  19. else?update(tr[x].lc,c),update(tr[x].rc,248)"> ????tr[x].c=tr[tr[x].lc].c+tr[tr[x].rc].c+(r-l+1)*tr[x].u;??
  20. }??
  21. LL?findans(int?x,LL?u)??
  22. if(!x)?return?u*(LL)(fr-fl+1);??
  23. if(l==fl&&fr==r)?return?tr[x].c+(LL)(r-l+1)*u;??
  24. if(fr<=mid)?return?findans(tr[x].lc,u+tr[x].u);??
  25. if(fl>mid)?return?findans(tr[x].rc,u+tr[x].u);??
  26. }??
  27. int?bt(int?r)??
  28. {??
  29. int?x=++trlen;??
  30. if(l!=r)??
  31. ????{??
  32. ???????? ????????tr[x].lc=bt(l,mid);??
  33. ????????tr[x].rc=bt(mid+1,r);??
  34. ????}??
  35. return?x;??
  36. void?change(int?k,248)"> ????update(root[x],1,n,c);??
  37. if(l==r)?return;??
  38. if(k<=mid)?change(tr[x].lc,k,153); font-weight:bold; background-color:inherit">else?change(tr[x].rc,248)"> int?solve(return?l;??
  39. int?mid=(l+r)/2;LL?sum=findans(root[tr[x].lc],0LL);??
  40. if(k<=sum)?return?solve(tr[x].lc,k);??
  41. return?solve(tr[x].rc,k-sum);??
  42. int?findnum( ????LL?k=(findans(root[1],0)-c+1);??
  43. if(k<=0)?k=1;??
  44. return?solve(1,N,k)-n-1;??
  45. int?main()??
  46. ????scanf("%d?%d",&n,&m);??
  47. ????N=2*n+1;bt(1,N);??
  48. for(int?i=1;i<=m;i++)??
  49. ????{??
  50. ????????int?tmp,x,y,c;scanf("%d?%d?%d?%d",&tmp,&x,&y,&c);??
  51. ????????if(tmp==1)?change(1,c+n+1,1LL);??
  52. ????????else?printf("%dn",findnum(x,(LL)c));??
  53. ????}??
  54. }??

数据生成器:

copy

    #include<ctime>??
  1. #include<iostream>??
  2. #define?LL?long?long??
  3. namespace?std;??
  4. }tr[400010];int?trlen=0;??
  5. if(!x)?x=++trlen;??
  6. return;}??
  7. int?mid=(l+r)/2;??
  8. ????tr[x].c=tr[tr[x].lc].c+tr[tr[x].rc].c+(r-l+1)*tr[x].u;??
  9. LL?findans(return?u*(LL)(fr-fl+1);??
  10. return?tr[x].c+(LL)(r-l+1)*u;??
  11. int?main()??
  12. ????srand(time(0));??
  13. int?n=7000,m=5000;??
  14. ????printf("%d?%dn",m);??
  15. int?l=rand()%n+1,r=rand()%n+1,c=(rand()%9000-rand()%9000)%n;??
  16. if(l>r)?swap(l,r);??
  17. int?tmp=rand()%2+1;??
  18. if(tmp==1)?update(root,153); font-weight:bold; background-color:inherit">else??
  19. ????????{??
  20. ????????????LL?TMP=findans(root,0);??
  21. ????????????if(TMP==0)?tmp=1;??
  22. ????????????else?c=rand()%TMP+1;??
  23. ????????}??
  24. ????????printf("%d?%d?%d?%dn",tmp,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> } ?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读