Desription
Analysis
65分想法:用堆维护一个最大值,暴力切割。
100分做法:
考虑一个有序序列a(当前蚯蚓长度)
每次必定是选择第一个,删除第一个,考虑把分裂出的插入序列,保证有序。
当切割一条蚯蚓
a1
时,设分成了
x1>y1
对于另一条蚯蚓
a2<a1
,它所分成的
x2>y2
必定也满足
x2<x1,y2<y1
可以用链表进行删除和插入。
利用这一性质,可以维护两个指针,分别表示x,y必定小于的数字。
显然可见,指针只会扫一遍。
所以复杂度是
O(n)
的
Code
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 101000, maxm = 7070000, maxq = 220, maxnum = 100100100;
int n,m,q,u,v,t;
int head,tot;
int xx,yy;
struct node{
int nex,las;
int num;
}a[(maxm + maxn) * 2];
bool cmp(node a,node b)
{
return a.num > b.num;
}
void inser(int x,int y)//把x插入到 y前一格
{
tot ++;
a[tot].num = x;
a[tot].las = a[y].las,a[a[y].las].nex = tot;
a[tot].nex = y,a[y].las = tot;
}
void delet(int x)//把x格删除
{
a[a[x].las].nex = a[x].nex;
a[a[x].nex].las = a[x].las;
a[x].nex = a[x].las = -1;
}
int main()
{
freopen("earthworm.in","r",stdin);freopen("earthworm.out","w",stdout);
//freopen("D:/LiuYuanHao/e.in","r",stdin);
//freopen("D:/LiuYuanHao/e.out","w",stdout);
scanf("%d%d%d%d%d%d", &n, &m, &q, &u, &v, &t);
for (int i = 1;i <= n;i ++)
{
int x;
scanf("%d", &x);
a[i].num = x;
}
sort(a + 1,a + 1 + n,cmp);
head = 1;
tot = n + 1;
a[n + 1].num = -2147483647;
a[1].nex = 2,a[n].las = n - 1,a[n].nex = n + 1,a[n + 1].las = n;
for (int i = 2;i <= n - 1;i ++)
a[i].las = i - 1,a[i].nex = i + 1;
double p = (double)u / v;
xx = 1, yy = 1;
int tt = 0;
for (int i = 1;i <= m;i ++)
{
int k;
a[head].num += (i - 1) * q;
if ((++ tt)%t==0) printf("%d ", a[head].num);
int tmp2 = a[head].num * p, tmp1 = a[head].num - tmp2; //tmp1 >= tmp2
k = xx;
while (a[k].num + i * q> tmp1/*- (i) * q/* && k > 0*/) k = a[k].nex;
inser(tmp1 - (i) * q,k);
xx = a[k].las;
k = yy;
while (a[k].num + i * q> tmp2/* - (i) * q/* && k > 0*/) k = a[k].nex;
inser(tmp2 - (i) * q,k);
yy = a[k].las;
head = a[head].nex;
delet(a[head].las);
}
printf("\n");
tt = 0;
for (int i = head;i != n + 1;i = a[i].nex)
{
if ((++ tt)%t==0)
printf("%d ", a[i].num + m * q);
}
}