{题解}[jzoj4907]【NOIP2016提高组复赛】蚯蚓

来源:互联网 发布:instsee新域名 编辑:程序博客网 时间:2024/05/23 07:25

传送门

Desription

图片

Analysis

65分想法:用维护一个最大值,暴力切割。
100分做法:
考虑一个有序序列a(当前蚯蚓长度)
每次必定是选择第一个,删除第一个,考虑把分裂出的插入序列,保证有序。
当切割一条蚯蚓a1时,设分成了x1>y1
对于另一条蚯蚓a2<a1必定也满足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);        }}
0 0
原创粉丝点击