2017.10.11离线赛总结

network ——3012

思路:这是一道比较奇葩的题(主要是题意描述不清吧),但看懂后,觉得这道题还是有套路可寻的,简而言之,就是一个神经元的c>0就可以传给与它相邻的神经元,那么输入时算它的度即可, 有起初有出度一定是出发点,可以想象神经元传来传去,到一定时刻它们的c都小于0就结束,这就很容易想到bfs。

maxlexicographic ——3110

思路:此题切分切了好几档,30分暴力,60dp,80贪心…100线段树维护。
30和60好说,但是这题怎么想都没想到是贪心…(也是考完看看数据范围才仔细揣摩贪心还是有可能的——考试时还是考虑不周)
80贪心:直接找第i个数之后哪个数比它大且在已剩步数内能完成,(考完后想想还是很好理解的…)
那么这里怎么想到要线段树呢?
还是基于贪心,找一个最大的数且已剩余步数内能完成的,但显然需要一个更快的查询方法,且找到这个最大数后还要进行快速的修改这个序列——快速查询+修改,那这不就是经典的线段树用处吗?

#include<bits/stdc++.h>
#define REP(i,f,t) for(int i=(f),i##_end_=(t);i<=i##_end_;i++)
#define DREP(i,f,t) for(int i=(f),i##_end_=(t);i>=i##_end_;i--)
#define root 1,n,1
#define lson L,mid,p<<1
#define rson mid+1,R,p<<1|1
#define family tree[p],tree[p<<1],tree[p<<1|1]
#define N 100005
using namespace std;
int n,m;
int A[N];

struct P80{
    void solve(){
        REP(i,1,n)scanf("%d",&A[i]);
        REP(i,1,n){
            int mx=A[i],k=-1;
            REP(j,i+1,n){
                if(A[j]>mx && j-i<=m)mx=A[j],k=j;
                else if(j-i>m)break;
            }
            if(k!=-1){
                DREP(j,k-1,i)swap(A[j],A[j+1]);
                m-=k-i;
            }
            if(m<=0)break;
        }
        REP(i,1,n)printf("%d\n",A[i]);
    }
}p60;

struct P100{
    int pos[N];
    struct node{
        int L,R,mx,step;
    }tree[N<<2];
    void Up(node &A,node &L,node &R){
        A.mx=max(L.mx,R.mx);
        A.step=L.step+R.step;
    }
    void build(int L,int R,int p){
        tree[p].L=L,tree[p].R=R;
        if(L==R){
            tree[p].step=1;
            tree[p].mx=A[L];
            return;
        } 
        int mid=(L+R)>>1;
        build(lson),build(rson);
        Up(family);
    }
    void update(int x,int p){
        if(tree[p].L==tree[p].R){
            tree[p].step=tree[p].mx=0;
            return;
        }
        int mid=(tree[p].L+tree[p].R)>>1;
        if(x<=mid)update(x,p<<1);
        else update(x,p<<1|1);
        Up(family);
    }
    int query(int L,int R,int p){
        if(tree[p].L==L && tree[p].R==R)return tree[p].step;
        int mid=(tree[p].L+tree[p].R)>>1;
        if(R<=mid)return query(L,R,p<<1);
        else if(L>mid)return query(L,R,p<<1|1);
        else return query(lson)+query(rson);
    }
    int Find(int tmp,int p){
        if(tree[p].L==tree[p].R)return tree[p].mx;
        if(tmp<tree[p<<1].step)return Find(tmp,p<<1);
        else return max(tree[p<<1].mx,Find(tmp-tree[p<<1].step,p<<1|1));
    }
    void solve(){
        REP(i,1,n)scanf("%d",&A[i]),pos[A[i]]=i; 
        build(root);
        REP(i,1,n){
            int id=Find(m,1);
            printf("%d\n",id);
            if(pos[id]>1)m-=query(1,pos[id]-1,1);
            update(pos[id],1);
        }
    }
}p100;
int main(){
//  freopen("maxlexicographic.in","r",stdin);
//  freopen("maxlexicographic.out","w",stdout);
    scanf("%d%d",&n,&m);
    if(n<=20000)p60.solve();
    else p100.solve();
    return 0;
}

lane ——3103

思路:此题考试时没怎么想…就敲了个暴力(这毕竟是到省选题)
这里要重点讲解:
My题解

小结:此次考试多处坑,分数切得也有点恶心…但是还是考很基础的东西——bfs,贪心…基础一定要打扎实了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值