P2827蚯蚓解题报告

无秒

2020-07-01 20:59:10

Personal

话说已经有n久都没写博客了,我又变懒了qwq,现在还在写NOIP的题,要么就是改题,模板的话老师说要写,但是不知道写啥(其实自己觉得很多都需要温习巩固一下,但是老师给的那个啥模板没几个会啊,然后在洛谷上搜模板,就把洛谷上我会的都差不多写了,然后一些写过的或者没在洛谷上看到的容易的,都没写,自我批评一下) 好了,进入正题,讲题。写这题主要是有点触动才写。 首先,这一看就是个堆嘛,直接用stl,但是我有点蠢(没吃,我感觉我最近智商下降了很多qwq,但愿我rp++吧),自以为是的想着记录时间,这样子算的更快,但是问题来了,我要开结构体,但是放到队列中又要重载运算符,但是我经过了n多的尝试,不得不放弃(平时写这些重载运算符都是对的啊,为什么会这个丫子,呜呜呜,难道队列要什么特殊的吗),所以我就放弃了记录时间,便直接干脆点,把他们氧化还原一波(变成最开始的情况),就是在算的时候才加上,然后分裂的时候肯定要把q减掉。 代码如下: ```cpp #include <cstdio> #include <iostream> #include <queue> #include <cstdlib> #include <functional> #include <cmath> using namespace std; #define isdigit(x) ((x)>='0'&&(x)<='9') #define ri register int priority_queue<int,vector<int>,less<int> >qq; int n,m,q,u,v,t,px,py,sum; double p; int a[100010]; inline void read(int &x) { x=0;char ch=getchar(); while(!isdigit(ch)) ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); } inline void write(int x) { char s[30];int top(0); while(x)s[++top]=x%10,x/=10; if(!top)putchar('0'); else while(top)putchar(s[top--]+'0'); putchar(' '); } int main() { read(n);read(m);read(q);read(u);read(v);read(t); p=(double)u/(double)v; for(ri i=1;i<=n;i++) read(px),qq.push(px); for(ri i=1;i<=m;i++) { py=qq.top()+sum;qq.pop(); if(i%t==0) write(py); px=floor(p*(double)py);py-=px; sum+=q; qq.push(px-sum);qq.push(py-sum); } putchar('\n'); for(ri i=1;i<=(n+m)/t*t;i++) { if(i%t==0) write(qq.top()+sum); qq.pop(); } return 0; } ``` 当然了,要是就这的话,那我也不用讲了,它也不配蓝题。就是其实有小细节,但是我们在考场上会怎么样呢?直接就这么过了。不能拿到满分。 so,我们要在考场上警惕,不能放过一丝一毫。蚯蚓要分成两段,很明显,长的分成的相应的一段必定大点,那么就分成三个数组,不用把它慢慢插入了,虽然只用logn,但在O(1)面前啥都不算qwq。所以呢,看时间复杂度是由提示的。 记起了hsx大佬的第四题,那也是的。本来它就需要你走幻境,你不能直接瞎跑啊,浪费了不少时间。所以正确做法应该是弄到一个点以后,假如它更小,那么就把不在队列,可以到达这个点的点弄进去,也就是把这个点更新了以后更新其他的。这样高效多了是不是? 代码如下: ```cpp #include <cstdio> #include <iostream> #include <queue> #include <cstdlib> #include <algorithm> #include <cmath> using namespace std; #define isdigit(x) ((x)>='0'&&(x)<='9') #define ri register int int cnt1[7000005],cnt2[7000005],now[7000005],qq[7100005]; int n,m,q,u,v,t,px,py,sum; int h1,h2,h3,r1,r2,r3,tot; double p; int a[100010]; inline void read(int &x) { x=0;char ch=getchar(); while(!isdigit(ch)) ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); } inline void write(int x) { char s[30];int top(0); while(x)s[++top]=x%10,x/=10; if(!top)putchar('0'); else while(top)putchar(s[top--]+'0'); putchar(' '); } bool cmp(const int a,const int b){return a>b;} inline int check() { if(h3>r3) { if(cnt1[h1]>cnt2[h2]) return cnt1[h1++]; else return cnt2[h2++]; } else if(now[h3]>=cnt1[h1]&&now[h3]>=cnt2[h2]) return now[h3++]; else if(cnt1[h1]>=cnt2[h2]&&cnt1[h1]>=now[h3]) return cnt1[h1++]; else return cnt2[h2++]; } inline void init() { for(int i=h3;i<=r3;i++) qq[++tot]=now[i]; for(int i=h1;i<=r1;i++) qq[++tot]=cnt1[i]; for(int i=h2;i<=r2;i++) qq[++tot]=cnt2[i]; } int main() { read(n);read(m);read(q);read(u);read(v);read(t); p=(double)u/(double)v; for(ri i=1;i<=n;i++) read(now[i]); sort(now+1,now+1+n,cmp); r3=n;r1=r2=0;h1=h2=h3=1; for(ri i=1;i<=m;i++) { py=check()+sum; if(i%t==0) write(py); px=floor(p*(double)py),py-=px; sum+=q;px-=sum,py-=sum; cnt1[++r1]=px,cnt2[++r2]=py; } putchar('\n'); init(); sort(qq+1,qq+1+tot,cmp); for(ri i=t;i<=tot;i+=t) if(i%t==0) write(qq[i]+sum); return 0; } ```