zoukankan      html  css  js  c++  java
  • 2019.08.22考试报告

    T1爬山

    首先我们发现一定先上山完再下山一定更优,

    设x为上山的次数,则n-x-1为下山的次数。

    则可以上的高度h1为[0,d*x],可以下的高度h2为[0,d*(n-x-1)];

    根据题意有:h1-h2=b-a;

    h1=h2+b-a,设等式前面为L,后面为R,

    那么0=<L<=d*x,b-a=<R<=d*(n-x-1)+b-a;

    所以只要L和R有交集就可以对答案作出贡献,

    即ans=min(d*x,d*(n-x-1)+b-a) (d*x>=b-a)

    这个式子是满足单峰的性质的,所以用三分求解,

    (然而$ O(1) $求解一元一次方程好像也可以?)

    最后把ans+=a即是最终答案。

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    int L,R,ans,n,d,a,b;
    int check(int x)
    {
            return min(d*x,d*(n-x-1)+b-a);
    }
    signed main()
    {
            //freopen("1.in","r",stdin);
            //freopen("1.out","w",stdout);
            scanf("%lld%lld%lld%lld",&n,&d,&a,&b);
            if(!d)
            {
                    printf("%lld",a);
                    return 0;
            }
            L=max((int)0,(b-a-1)/d+1),R=n-1;
            while(L<R-1)
            {
                    int l=L+(R-L+1)/3;
                    int r=R-(R-L+1)/3;
                    if(check(l)<check(r)) L=l;
                    else R=r;
            }
            if(L>R) ans=0;
            else ans=max(check(L),check(R));
            printf("%lld",ans+a);
            return 0;
    }
    T1

    T2学数数

    答案很大,显然ans++的算法是会T的。

    我们考虑对于每一个位置处理出以它为最大值的区间的左右边界L,R,

    即[L,i][i,R]的子数组最大值都是a[i]。

    预处理复杂度二分$ O(nlog2(n)) $或者单调栈$ O(n) $

    之后按最大值排序,每次询问就在序列里二分查询即可。

    查询复杂度$ O(Qlog2(n))。

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=1e5+10;
    int ans,n,q,a[N],st[N][30],c[N],sum[N];
    char s[5];
    map<int,int>ma;
    struct point
    {
            int val,l,r,sum;
            friend bool operator <(point a,point b)
            {
                    return a.val<b.val;
            }
    };
    vector<point>v;
    void init()
    {
            for(int i=1;i<=n;i++)
            {
                    st[i][0]=a[i];
            }
            for(int j=1;j<=25;j++)
            {
                    for(int i=1;i+(1<<(j-1))<=n;i++)
                    {
                            st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
                    }
            }
    }
    int get(int l,int r)
    {
            int k=log2(r-l+1);
            return max(st[l][k],st[r-(1<<k)+1][k]);
    }
    void work1(int x)
    {
            if(x>=v[n-1].val) 
            {
                    ans=0;
                    return;
            }
            int L=0,R=n-1;
            while(L<R)
            {
                    int mid=(L+R)>>1;
                    if(v[mid].val<=x) L=mid+1;
                    else R=mid;
            }
            ans=sum[n]-sum[L];
    }
    void work2(int x)
    {
            ans=ma[x];
    }
    void work3(int x)
    {
            if(x<=v[0].val)
            {
                    ans=0;
                    return;
            }
            int L=0,R=n-1;
            while(L<R)
            {
                    int mid=(L+R+1)>>1;
                    if(v[mid].val<x) L=mid;
                    else R=mid-1;
            }
            ans=sum[L+1];
    }
    signed main()
    {
            //freopen("1.in","r",stdin);
            //freopen("2.out","w",stdout);
            scanf("%lld%lld",&n,&q);
            for(int i=1;i<=n;i++)
            {
                    scanf("%lld",&a[i]);
            }
            init();
            for(int i=1,L,R;i<=n;i++)
            {
                    point S;
                    S.val=a[i];
                    L=1,R=i-1;
                    while(L<R)
                    {
                            int mid=(L+R)>>1;
                            if(get(mid,i-1)>=a[i]) L=mid+1;
                            else R=mid;
                    }
                    if(L==i-1&&a[i-1]>=a[i]) L++;
                    S.l=L;
                    L=i+1,R=n;
                    while(L<R)
                    {
                            int mid=(L+R+1)>>1;
                            if(get(i+1,mid)>a[i]) R=mid-1;
                            else L=mid;
                    }
                    if(R==i+1&&a[i+1]>a[i]) R--;
                    S.r=R;
                    S.sum=(S.r-i+1)*(i-S.l+1);
                    v.push_back(S);
            }
            sort(v.begin(),v.end());
            for(int i=0;i<n;i++)
            {
                    sum[i+1]=sum[i]+v[i].sum;
                    ma[v[i].val]+=v[i].sum;
            }
            for(int i=1,k;i<=q;i++)
            {
                    scanf("%s%lld",s,&k);
                    if(s[0]=='>') work1(k);
                    if(s[0]=='=') work2(k);
                    if(s[0]=='<') work3(k);
                    printf("%lld
    ",ans);
            }
            return 0;
    }
    T2

    T3七十和十七

    题解在这里

    考试总结:

    考试不是很满意,只拿到了大众分220分,T3既不会找规律也不会正解。

    打完T1T2正解+暴力+对拍以及T3暴力之后思考量几乎降为了0,

    只在临近尾声查出T1的一个错,这与我上上次考试比起来显得大相径庭。

    (成语用的不好不要怪我哦~语文年级1000+)

    还是对自己要求不够高啊,照这状态怎么回第一机房做难到自闭的A卷呢。

  • 相关阅读:
    LeetCode 647. Palindromic Substrings
    jquery--find与children方法的区别
    JavaScript MVC框架PK:Angular、Backbone、CanJS与Ember
    javascript之原型prototype
    js的数据格式之json
    Javascript:必须知道的Javascript知识点之“单线程事件驱动”
    javascript自我测试题
    javascript:delete 删除对象的属性
    javascript:function 函数声明和函数表达式 详解
    [转]JavaScript可否多线程? 深入理解JavaScript定时机制
  • 原文地址:https://www.cnblogs.com/AthosD/p/11393637.html
Copyright © 2011-2022 走看看