2017-10-19离线赛总结

来源:互联网 发布:数据透视表 值 合计 编辑:程序博客网 时间:2024/06/06 06:51

失分小结:
估分:250
实际分数:145
这次又翻水水,本以为这次可以考的不错
结果第一题就wa了(字符串多输出了一位类似于空格的东西,看不见。。。)
第二题神判数据范围,切少了10分
第三题没什么时间,丢上去一个最无脑的暴力,还多水了5分

题解:
第二题这种贪心题目,就是推一推 然后大胆地猜想 再拿暴力对拍
所以一定要先打暴力!
第三题
这种在轴上单向移动的题目,都可归结到倍增上 虽然考试时只顾着打暴力,屁都没想到
因为A和B的顺序是固定的 这么水的题,条件都那么显然
那么就把AB都走一步记为一步
走完这后在判断A能不能再走一步
这样解决的复杂度就为mlogn
由于n<=100000
预处理复杂度不能在n2级上
解法有很多 (后缀BIT,权值线段树,链表,multiset)虽然我只写了一种 复杂度都为nlogn

代码实现:

#include<cstdio>#include<algorithm>#include<set>using namespace std;#define FOR(i,x,y) for(int i=(x);i<=(y);i++)#define DOR(i,x,y) for(int i=(x);i>=(y);i--)#define ll long long#define INF 1000000000000#define M 100005#define S 20 inline ll Abs(ll x){return x>0?x:-x;}ll H[M];int fa[S][M];struct node{    int id;ll v;    bool operator <(const node &_)const{return v<_.v;}}A[M],B[M];struct node1{ll a,b;}len[S][M];multiset<node>mt;multiset<node>::iterator it;int n,m;void init(){    mt.insert((node){0,-INF});    mt.insert((node){0,-INF});    mt.insert((node){0,INF});    mt.insert((node){0,INF});    node tmp[4];    DOR(i,n,1){        mt.insert((node){i,H[i]});        it=mt.find((node){i,H[i]});        tmp[2]=*(++it);tmp[2].v=Abs(tmp[2].v-H[i]);        tmp[3]=*(++it);tmp[3].v=Abs(tmp[3].v-H[i]);        --it;--it;        tmp[0]=*(--it);tmp[0].v=Abs(H[i]-tmp[0].v);        tmp[1]=*(--it);tmp[1].v=Abs(H[i]-tmp[1].v);        stable_sort(tmp,tmp+4);        A[i]=tmp[1];        B[i]=tmp[0];        fa[0][i]=B[tmp[1].id].id;        len[0][i].a=tmp[1].v;        len[0][i].b=B[tmp[1].id].v;    }    FOR(i,1,S-1)FOR(j,1,n){        fa[i][j]=fa[i-1][fa[i-1][j]];        len[i][j].a=len[i-1][j].a+len[i-1][fa[i-1][j]].a;        len[i][j].b=len[i-1][j].b+len[i-1][fa[i-1][j]].b;    }}node1 solve(int now,int mx){    ll a=0,b=0;    DOR(i,S-1,0)        if(fa[i][now]!=0&&len[i][now].a+len[i][now].b+a+b<=mx){            a+=len[i][now].a;            b+=len[i][now].b;            now=fa[i][now];        }    if(A[now].id!=0&&A[now].v+a+b<=mx){        a+=A[now].v;    }    return (node1){a,b};}int main(){    scanf("%d",&n);    FOR(i,1,n)scanf("%lld",&H[i]);    init();    ll mx;    scanf("%lld%d",&mx,&m);    int ans=0;    double d=-1;    FOR(i,1,n){        node1 x=solve(i,mx);        ll a=x.a,b=x.b;        if(a==0||b==0){            if(d==-1&&H[i]>H[ans])ans=i;        }        else {            double res=1.0*a/b;            if((res<d||d==-1)||(d==res&&H[i]>H[ans]))d=res,ans=i;        }    }    printf("%d\n",ans);    FOR(i,1,m){        int now;        scanf("%d%lld",&now,&mx);        node1 x=solve(now,mx);        printf("%lld %lld\n",x.a,x.b);    }    return 0;}