ARC 072

来源:互联网 发布:小说编写软件 编辑:程序博客网 时间:2024/06/05 11:36

C
相邻前缀不相同就是没有0
只有+-+-+-和-+-+-+两种情况,枚举
每个位置加减会改变后面所有前缀和,所以这个位置只要修改到符合符号就行了

D
(打表)发现|X-Y|<=1时先手必败

E
记从1开始走到i时刻前距离终点di,发现witch就是把di+1变成0~di的一个数
维护一个最大的now表示i这个时刻后,距离终点0~now都一定能到达终点,i=n时now=0,然后从n往前递推,
当ai<=now+1或ai>now+1且ai-(now+1)<=now时now+=ai,
否则now不变,
di>now时witch能让他变成now+1使其不能到达终点

code:

#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long longusing namespace std;const int maxn = 610000;int n,Q,D,ed;int a[maxn],d[maxn];int ok[maxn];int main(){    scanf("%d%d",&n,&D);    for(int i=1;i<=n;i++) scanf("%d",&a[i]);    int tmp=D;    for(int i=1;i<=n;i++) if(a[i]<tmp*2)     {        d[i]=tmp;        tmp=a[i]>tmp?a[i]-tmp:tmp-a[i];        if(!tmp) { ed=i; break; }    }    if(tmp) for(int i=1;i<=n;i++) ok[i]=1;    else    {        int now=0;        for(int i=n;i>=1;i--)        {            int x=a[i+1];            if((x-(now+1)<=now)) now+=x;            if(ed<i) { ok[i]=0; continue; }            if(d[i]>now) ok[i]=1;        }    }    scanf("%d",&Q);    while(Q--)    {        int x; scanf("%d",&x);        puts(ok[x]?"YES":"NO");    }    return 0;}

F
用一个二元组(x,y)表示水量有x升,x*temperature=y,的状态,
维护第i天水量为j的最大温度f[i][j],将f[i][j]表示在二维平面上,j为横坐标,f[i][j]为纵坐标,发现是一些这些,比如f[1][L]就是一条连接(0,0)和(v,vt)的线段。
每一天,会在头部连上一条线段,可以发现维护一个上凸的凸包一定保证每个j的f[i][j]最优

code:

#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long long using namespace std;const int maxn = 510000;int n,L;struct node{double x,y;}a[maxn<<1]; int head,tail;double multi(node x,node y,node z){    x.x-=z.x; x.y-=z.y;    y.x-=z.x; y.y-=z.y;    return x.x*y.y-x.y*y.x;}int main(){    scanf("%d%d",&n,&L); n--;    a[head=maxn]=(node){0.0,0.0};    ll x,y;    tail=head+1; scanf("%lld%lld",&y,&x);    printf("%lf\n",(double)y); a[tail].y=(double)x*y; a[tail].x=x;    for(int i=1;i<=n;i++)    {        scanf("%lld%lld",&y,&x); y*=x;        node now=(node){a[head].x-(double)x,a[head].y-(double)y};        while(head+1<=tail&&a[tail-1].x-now.x>=L) tail--;        if(head!=tail)        {            double pt=(a[tail].y-a[tail-1].y)/(a[tail].x-a[tail-1].x);            if(a[tail].x-now.x>L)            {                a[tail].y=a[tail-1].y+(L-(a[tail-1].x-now.x))*pt;                a[tail].x=now.x+L;            }        }        while(head+1<=tail&&multi(a[head],a[head+1],now)>=0) head++;        a[--head]=now;        double kk=a[tail].y-now.y;        printf("%lf\n",kk/(double)L);    }    return 0;}
原创粉丝点击