codeforces 1792D Fixed Prefix Permutations

16 篇文章 0 订阅
5 篇文章 0 订阅
文章讨论了一种算法问题,即寻找数组a中的元素a_i与数组b中元素的最长公共前缀。通过对b数组进行排序,然后使用二分查找找到与a_i最接近的元素,以O(mnlogn)的时间复杂度求解,降低了原始算法的复杂度。
摘要由CSDN通过智能技术生成

Fixed Prefix Permutations

i − − > p i − − > q p i i-->p_i-->q_{pi} i>pi>qpi
要满足条件 i = q p i i=q_{pi} i=qpi,那么只需 q j = i q_j=i qj=i中的 j = p i j=p_i j=pi
为此我们求出每个数字在数组中的pos,存在b中
之后验证只需查看 a i a_i ai , b j b_j bj中最长共前缀

对于一个 a i a_i ai 暴力查找 最长公共前缀的 b j b_j bj 需要O(n*m),再循环操作总共需要 O ( m n 2 ) O(m n^2) O(mn2)
先对 b b b 整体排序,之后二分查找与 a i a_i ai 最相近的 b j b_j bj 即可 排序预处理 总时间复杂度为 O ( m n l o g n ) O(mnlogn) O(mnlogn)

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int lcp(vector<int> a,vector<int> b){
    int i=1;
    for (i=1;a[i]==b[i]&&i<a.size();i++){
        ;
    }
    return i-1;
}
void solve(){
    int n,m;
    cin>>n>>m;
    vector<vector<int>> a(n+1,vector<int>(m+1)),b(n+1,vector<int>(m+1));
    for (int i=1;i<=n;i++){
        for (int j=1;j<=m;j++){
            cin>>a[i][j];
            b[i][a[i][j]]=j;
        }
    }
    sort(b.begin()+1,b.end());
    for (int i=1;i<=n;i++){
        int p=lower_bound(b.begin()+1,b.end(),a[i])-b.begin(),ans=0;
        if (p>=2) ans=max(ans,lcp(a[i],b[p-1]));
        if (p<=n) ans=max(ans,lcp(a[i],b[p]));
        cout<<ans<<" ";
    }
    cout<<"\n";
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int t;
    cin>>t;
    while (t--){
        solve();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值