[关闭]
@nlogn 2019-01-23T02:40:49.000000Z 字数 3119 阅读 522

LogeYOI Winter Day1题解

注:本题解代码均已开启反作弊功能。

前言

18:40比赛就开始了,给我说的时候已经19:20了,,,

我少了40min的做题时间,以至于只拿到了150pts。

自闭了,我菜死了。

5jripi.jpg

成绩单 (Rank10)

5jchad.png

强死了啊啊啊啊啊啊啊!

A

题面

5jrY9i.png
5jr0by.png

分析

这题面对可爱的真的不太友好(逃

显然我们可以暴力。

从题面得知,这是一棵二叉树,所以满足一个性质:

如果一个节点编号为,那么它的左右子节点编号分别为.

对于每一次询问,查看这个点是否为Gay点,如果不是,那么往上跳。

直到调到根节点为止。

代码

  1. /* Headers */
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<cctype>
  6. #include<iostream>
  7. using namespace std;
  8. namespace FastIO{
  9. const int BUFSIZE=1<<20;
  10. char ibuf[BUFSIZE],*is=ibuf,*it=ibuf;
  11. char obuf[BUFSIZE],*os=obuf,*ot=obuf+BUFSIZE;
  12. inline char getch(){
  13. if(is==it)
  14. it=(is=ibuf)+fread(ibuf,1,BUFSIZE,stdin);
  15. return (is==it)?EOF:*is++;
  16. }
  17. inline int getint(){
  18. int res=0,neg=0,ch=getch();
  19. while(!(isdigit(ch)||ch=='-')&&ch!=EOF)
  20. ch=getch();
  21. if(ch=='-'){
  22. neg=1;ch=getch();
  23. }
  24. while(isdigit(ch)){
  25. res=(res<<3)+(res<<1)+(ch-'0');
  26. ch=getch();
  27. }
  28. return neg?-res:res;
  29. }
  30. inline void flush(){
  31. fwrite(obuf,1,os-obuf,stdout);
  32. os=obuf;
  33. }
  34. inline void putch(char ch){
  35. *os++=ch;
  36. if(os==ot) flush();
  37. }
  38. inline void putint(int res){
  39. static char q[10];
  40. if(res==0) putch('0');
  41. else if(res<0){
  42. putch('-');
  43. res=-res;
  44. }
  45. int top=0;
  46. while(res){
  47. q[top++]=res%10+'0';
  48. res/=10;
  49. }
  50. while(top--) putch(q[top]);
  51. }
  52. }
  53. using namespace FastIO;
  54. /* definitions */
  55. const int MAXN = 2e6+7;
  56. struct Node{
  57. int father;
  58. bool gay;
  59. };
  60. Node Tree[MAXN];
  61. int n,m,q;
  62. int Gay[MAXN];
  63. int TO[MAXN];
  64. bool PRINT[MAXN];
  65. bool flag;
  66. /* functions */
  67. inline void DFS(int p){
  68. if(p==1){
  69. printf("srO lgy Orz\n");
  70. return;
  71. }
  72. while(p>1){
  73. if(Tree[p].gay==true){
  74. printf("LoGAY!\n");
  75. //PRINT[p]=true;
  76. flag=true;
  77. return;
  78. }
  79. p=Tree[p].father;
  80. //cout<<p<<" ";
  81. }
  82. if(!flag) printf("srO lgy Orz\n");
  83. }
  84. int main(int argc,char *argv[]){
  85. freopen("tree.in","r",stdin);
  86. freopen("tree.out","w",stdout);
  87. scanf("%d%d",&n,&m);
  88. for(int i=1;i<=m;i++){
  89. int x;
  90. scanf("%d",&x);
  91. Tree[x].gay=true;
  92. }
  93. scanf("%d",&q);
  94. for(int i=1;i<=q;i++){
  95. scanf("%d",&TO[i]);
  96. if(TO[i]%2==0)Tree[TO[i]].father=TO[i]/2;
  97. else Tree[TO[i]].father=(TO[i]-1)/2;
  98. DFS(TO[i]);
  99. }
  100. fclose(stdin);
  101. fclose(stdout);
  102. return 0;
  103. }

B

题面

5jr4DG.png
5jrsNK.png

分析

怎么这么惨啊QAQ(再逃

其实看到这题,我第一反应是:

普及组考Treap!

而我只是知道Treap可以求区间第小,而且还是的,具体实现,连原理我都不知道啊啊啊啊啊啊。

心态崩了,每日一崩。

但实际上不用,虽然大神犇说可以线段树+二分

当时我心态就又崩了,我是不是学了假的线段树啊啊啊啊啊。(一定是我太菜了)

用两个堆维护求区间第小值的查询。(一个大根堆,一个小根堆)

对于每一次输入的2操作,我们定义一个r=q+1,然后从r循环到q,把1操作的东西插入进大根堆,如果这时大跟堆中有个元素,那么就把大根堆的堆顶push进小根堆里。

如此循环执行之后,输出小根堆堆顶即可。

附图自行理解:

5jrK19.png

代码

  1. /* Headers */
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<cctype>
  6. #include<algorithm>
  7. #include<queue>
  8. #include<vector>
  9. using namespace std;
  10. /* definitions */
  11. const int MAXN = 2e6+7;
  12. priority_queue<int,vector<int>,greater<int> > MinQ;
  13. priority_queue<int> MaxQ;
  14. int Buck[MAXN];
  15. int n,m,q;
  16. int r=1;
  17. /* functions */
  18. inline void Queue(){
  19. scanf("%d%d",&n,&m);
  20. for(int i=1;i<=n;i++)scanf("%d",&Buck[i]);
  21. for(int i=1;i<=m;i++){
  22. scanf("%d",&q);
  23. for(int j=r;j<q;j++){
  24. MaxQ.push(Buck[j]);
  25. if(MaxQ.size()==i){
  26. MinQ.push(MaxQ.top());
  27. MaxQ.pop();
  28. }
  29. }
  30. r=q+1;
  31. printf("%d\n",MinQ.top());
  32. MaxQ.push(MinQ.top());
  33. MaxQ.pop();
  34. }
  35. return;
  36. }
  37. int main(int argc,char *argv[]){
  38. freopen("bucket.in","r",stdin);
  39. freopen("bucket.out","w",stdout);
  40. Queue();
  41. fclose(stdin);
  42. fclose(stdout);
  43. return 0;
  44. }

C

题面

5jr6rq.png
5jrtdO.png

分析

首先我们一眼就能找到的规律。

  1. inline void init(){
  2. int ans=0;
  3. scanf("%d%d",&n,&m);
  4. for(int i=1;i<=n;i++){
  5. int x;
  6. scanf("%d",&x);
  7. ans+=x;
  8. }
  9. for(int j=1;j<=m;j++){
  10. int a,b,c;
  11. scanf("%d%d%d",&a,&b,&c);
  12. Add_Edge(a,b,c);
  13. Add_Edge(a,b,c)
  14. }
  15. printf("%d\n",ans);
  16. }

其他90pts

大爷不肯给我讲啊啊啊啊啊,怎么办啊啊啊啊啊啊,
一定是我太菜了,滚~

THE END

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注