看到题目就能够想到直接开的堆模拟的过程了吧,这个仍是很naive的git
注意在用堆作的时候也是要明智一点的,对于蚯蚓长度的相加确定不能直接遍历并加上,仍是能够差分一下的spa
其实说白了就是把集体加->单体减的一个小技巧,仍是挺经常使用的。code
而后看这个数据范围猜测应该是有什么\(O(n)\)的作法的,而后这就要发现题目中隐含的单调性队列
咱们考虑讲全部的蚯蚓分个类,全部初始时没切割过的蚯蚓分为一类,每次切割产生的较长的蚯蚓分为一类,而产生的较短的蚯蚓分为一类it
而后咱们推到一下就能够发现,对于后面的两类蚯蚓,它们知足单调性io
由于咱们根据切割的过程能够发现:class
因此咱们再对初始的蚯蚓长度拍个序,就能够获得三个单调的队列(注意不是单调队列),每一次比较时咱们取出队首并切割最长的一只再丢进第二队,第三队便可遍历
差分的思想仍是要的,不过这里直接记录了每一只蚯蚓进队的时间,每次注意加上增加的长度技巧
细节比较多,最后对这三队蚯蚓作一次归并便可(由于都是有序的)数据
所以复杂度为\(O(n\ logn+m)\)
CODE
#include<cstdio> #include<cctype> #include<algorithm> using namespace std; const int N=100005,M=7000005; int n,m,q,u,v,t,a[N],que[3][M],num[3][M],H[3],T[3],cut[M],ans[N+M],temp[N+M],cnt,tot; inline char tc(void) { static char fl[100000],*A=fl,*B=fl; return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++; } inline void read(int &x) { x=0; char ch; while (!isdigit(ch=tc())); while (x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc())); } inline void write(int x) { if (x>9) write(x/10); putchar(x%10+'0'); } inline bool cmp(int x,int y) { return x>y; } inline void swap(int &a,int &b) { int t=a; a=b; b=t; } inline void merge(void) { register int i=H[0],j=H[1]; while (i<=T[0]&&j<=T[1]) if (que[0][i]+(m-num[0][i])*q>que[1][j]+(m-num[1][j])*q) temp[++cnt]=que[0][i]+(m-num[0][i])*q,++i; else temp[++cnt]=que[1][j]+(m-num[1][j])*q,++j; for (;i<=T[0];++i) temp[++cnt]=que[0][i]+(m-num[0][i])*q; for (;j<=T[1];++j) temp[++cnt]=que[1][j]+(m-num[1][j])*q; i=1; j=H[2]; while (i<=cnt&&j<=T[2]) if (temp[i]>que[2][j]+(m-num[2][j])*q) ans[++tot]=temp[i],++i; else ans[++tot]=que[2][j]+(m-num[2][j])*q,++j; for (;i<=cnt;++i) ans[++tot]=temp[i]; for (;j<=T[2];++j) ans[++tot]=que[2][j]+(m-num[2][j])*q; } inline void print(void) { for (register int i=t;i<=m;i+=t) write(cut[i]),putchar(' '); putchar('\n'); for (register int i=t;i<=n+m;i+=t) write(ans[i]),putchar(' '); } int main() { //freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout); register int i,j; read(n); read(m); read(q); read(u); read(v); read(t); for (i=1;i<=n;++i) read(a[i]); sort(a+1,a+n+1,cmp); for (i=1;i<=n;++i) que[0][++T[0]]=a[i]; H[0]=H[1]=H[2]=1; for (i=1;i<=m;++i) { int len=-1,id; for (j=0;j<3;++j) if (H[j]<=T[j]) if (que[j][H[j]]+(i-num[j][H[j]]-1)*q>len) len=que[j][H[j]]+(i-num[j][H[j]]-1)*q,id=j; cut[i]=len; ++H[id]; int x=1LL*len*u/v,y=len-x; if (x<y) swap(x,y); que[1][++T[1]]=x; num[1][T[1]]=i; que[2][++T[2]]=y; num[2][T[2]]=i; } merge(); print(); return 0; }