P6155 修改

P6155 修改

昨晚没睡好,早上状态让人难绷。


容易想到将 a a a 从大到小排序,依次找到合法的 a i ′ a'_i ai,记修改 a i → a i ′ a_i\rarr a'_i aiai 为次数为 p i p_i pi,将 p i , b i p_i,b_i pi,bi 逆序相乘即为答案。

考虑如何求解 a i ′ a'_i ai,这是一个类似求 mex 的问题。

S o l u t i o n   1 Solution\ 1 Solution 1

联想到 [CSP-S 2023] 消消乐。可以看下题解的图,很像本题求 mex 的过程,想到可以用并查集求解。

不过我晕乎乎的没敢写。

int find(int x){
	if(f[x]==0)return f[x]=x+1;
	return f[x]=find(f[x]);
}

扫一遍 a i a_i ai 即可,由于 R ( f ) ∈ [ 1 , 1 0 9 ] \R(f)\in [1,10^9] R(f)[1,109],用 unordered_map 复杂度大概 O ( N log ⁡ 2 N ) O(N\log^2N) O(Nlog2N)

S o l u t i o n   2 Solution\ 2 Solution 2

根据贪心策略,当 a i < a j a_i<a_j ai<aj 时,若 a i a_i ai 至少要增大到 a j a_j aj ,此时 a i a_i ai 跨越 a j a_j aj 更优。

这个性质表现为包含性,类似括号序列。假如我们从左向右扫,满足后进先出,因此可以用栈模拟过程。
具体地,值域上每个位置 x x x 可以放一个 a i a_i ai,因此扫一遍值域,加入 a i a_i ai 的同时要求每个 x x x 上最多只能弹出一个 a i a_i ai。值域 1 0 9 10^9 109,由于 n ≤ 1 0 5 n\le 10^5 n105,意味着 a i a_i ai 最多需要 1 0 5 10^5 105 个位置,因此可以当栈空时手动跳到下一个 a i a_i ai 所在位置,复杂度 O ( n ) O(n) O(n)

#include<bits/stdc++.h>
#define rep(i,a,b) for(register int i=a;i<=b;i++)
#define dec(i,a,b) for(register int i=a;i>=b;i--)
using namespace std;
typedef unsigned long long ull;
const int N=1e6+5;
int n,a[N],b[N],p0,p[N];
ull ans;
inline int Rd(){
    int s=0,w=1;char ch=getchar();
    while (ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
    while (ch>='0'&&ch<='9') s=(s<<1)+(s<<3)+ch-'0',ch=getchar();
    return s*w;
}
int main(){
    n=Rd();
    rep(i,1,n) a[i]=Rd();rep(i,1,n) b[i]=Rd();
    sort(a+1,a+n+1);sort(b+1,b+n+1,greater<int>());
    stack<int> st;
    int nw=1,x=1;
    auto Push=[&](){while (nw<=n&&a[nw]==x) st.push(a[nw++]);};
    while (1){
        if(st.empty()){
            if(nw<=n) x=a[nw],Push();
            else break;
        }
        else Push();
        p[++p0]=(x++)-st.top();st.pop();
    }
    sort(p+1,p+n+1);
    rep(i,1,n) ans+=1llu*b[i]*p[i];
    printf("%llu",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值