题解 CF2164C Dungeon

· · 题解

题解 CF2164C Dungeon

其他题

题意

n 把剑,m 个怪,剑有攻击力 a_i,怪有防御力 b_j。剑 i 能杀死怪 j 当且仅当 a_i\ge b_j

怪分两类:

一个怪只能打一次,求最多能打死多少怪。

数据范围:多测,\sum n,\sum m\le 2\times10^5a_i,b_i,c_i\le 10^9

做法

显然要先打能爆装备的怪。而为了尽量使剑增强,每个这种怪都应该用尽量烂的剑去打。为了防止有怪不强化就打不死的情况打的时候按 b_i 排个序。这可以用 multiset 维护,不会写也可以上树。

然后对于不爆装备的就枚举每个怪找最菜的剑打就行,顺序随意因为反正我每次用的是最菜的剑,打谁都一样。

:::success[代码] 关于 setmultiset 的基本操作:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<fstream>
#include<algorithm>
#include<map>
#include<unordered_map>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#define ll long long
#define lf double
#define ld long double
using namespace std;
struct node{
    ll b,c;
};
bool operator <(node x,node y){
    return x.b==y.b?x.c>y.c:x.b<y.b;
}
ll T,n,m,u,b[200010],p1,p0,ans;
multiset<ll> s;
node c[200010];
int main(){
    ios::sync_with_stdio(0);
    cin>>T;
    while(T--){
        cin>>n>>m;
        s.clear();p0=p1=ans=0;
        for(int i=0;i<n;i++){
            cin>>u;
            s.insert(u);
        }
        for(int i=0;i<m;i++){
            cin>>b[i];
        }
        for(int i=0;i<m;i++){
            cin>>u;
            if(u){
                c[p1].b=b[i];
                c[p1++].c=u;
            }
            else{
                b[p0++]=b[i];
            }
        }
        sort(b,b+p0);
        sort(c,c+p1);
        for(int i=0;i<p1;i++){
            set<ll>::iterator p=s.lower_bound(c[i].b);
            if(p==s.end()){
                break;
            }
            ans++;
            ll tmp=(*p);
            s.erase(p);
            s.insert(max(tmp,c[i].c));
        }
        for(int i=0;i<p0;i++){
            set<ll>::iterator p=s.lower_bound(b[i]);
            if(p==s.end()){
                break;
            }
            ans++;
            s.erase(p);
        }
        cout<<ans<<endl;
    }
    return 0;
}

:::