2022 ccpc 广东省赛 J 新英雄

--------赛时--------

这道题蛮心酸的

也蛮玄学的

赛时队友和我都没想到正解,队友愣是用其强大的算力写出几个不等式然后处理了一车细节...

wa on test 5

我写了一个从后往前的贪心...

wa on test 4

赛后看了题解发现里面有个N*logN,哪来的logN?

突然意识到喵的区间该不会是不保证有序的吧

冲回来把队友代码改了一下..过了.....跑得贼快........

q..但是我的并没有,并且经过努力终于wa on 9

然后造了好几个数据才把自己hack了,就是从后往前我的写法处理不了法力为0时的情况

----------正解---------

考虑每次把能攒的法力都攒了,遇到友方就攒,如果遇到敌方过不去,就反复横跳

那这样会浪费怎么办?

在O(n)扫完一遍后,假设剩x个法力,用了y的时间

那么我们就可以把x个法力消耗完,减少y的时间

这样做的正确性是如果有x点法力,起码经过了x个英雄,肯定是可以用完的

因为如果消耗了1法力,来回差值其实是2,原本用的时间是3,那么用完法力后就是1,时间减少2

所以法力减少2,时间减少2

妙!!像是那种可以反悔的贪心,放最后才来处理后效性

突然想到如果把数值改改也是可以的..

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct lys{
    ll l,r,t;
}a[int(1e6)],f[int(1e6)];
bool cmp(lys a,lys b){
    return a.l<b.l;
}
int main(){
    //freopen("lys.in","r",stdin);
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=m;i++) cin>>f[i].t>>f[i].l>>f[i].r;
    sort(f+1,f+m+1,cmp);
    int cnt=0;
    f[0].t=1;f[0].r=f[0].l=0;
    a[0].t=1;a[0].r=a[0].l=0;
    for(int i=1;i<=m;i++){
        if(f[i].t==a[cnt].t){
            a[cnt].r=f[i].r;
        }
        else {
            cnt++;a[cnt].l=f[i].l;a[cnt].r=f[i].r;a[cnt].t=f[i].t;
        }
    }
    if(a[0].r==0) {
        cout<<"0/21/0"<<endl; return 0;
    }
    ll tot=0,magic=0;
    for(int i=0;i<=cnt;i++){
        ll len=a[i].r-a[i].l+1;
        if(i==0) len--;
        if(a[i].t==2){
            if(magic<len){
                ll d=len-magic;
                if(d%2==1) d++;
                tot+=d*3;// before 
                magic+=d;
            }// zan
            tot+=len;// now len*1
            magic-=len;
        }
        else {
            tot+=len*3;
            magic+=len;
        }
        //cout<<tot<<" "<<magic<<endl;
    }
    tot-=((magic)/2)*2;
    cout<<tot;
}

 

posted @ 2022-08-09 10:11  liyishui  阅读(117)  评论(0编辑  收藏  举报