Educational Codeforces Round 142 (Rated for Div. 2)

D. Fixed Prefix Permutations

题目大意
给定两个排列p,qr=pq表示rj=qpj
一个排列p的美丽值为满足p1=1, p2=2, p3=3, , pk=k最大的k,若p11,则k=0
现给定n个长度一样的排列a[n],输出n个答案,第i个答案表示aiaj (1jn)的最大美丽值。

解题思路
k0的情况下我们有pq=(1, 2, , k, rk+1, , ,rm),两边同时乘以q1p1pq1=(1, 2, , n)得到p=(1, 2, , k, rk+1, , ,rm)q1,我们会发现p的前k个数与q1k个数相同。那么要找大最大的k,就是对p而言找到具有最长相同前缀的q1

参考代码

#include <bits/stdc++.h>
using namespace std;
int get(vector<int> &a, vector<int> &b)
{
    int ans = 0;
    while (ans < a.size() && a[ans] == b[ans])
    {
        ++ans;
    }
    return ans;
}
void work()
{
    int n, m;
    cin >> n >> m;
    vector<vector<int>> a(n, vector<int>(m));
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j)
        {
            cin >> a[i][j];
            --a[i][j];
        }
    }
    vector<vector<int>> b(n, vector<int>(m));
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j)
        {
            b[i][a[i][j]] = j;
        }
    }
    sort(b.begin(), b.end());
    for (int i = 0; i < n; ++i)
    {
        int ans = 0;
        int t = lower_bound(b.begin(), b.end(), a[i]) - b.begin();
        if (t > 0)
            ans = max(ans, get(b[t - 1], a[i]));
        if (t < n)
            ans = max(ans, get(b[t], a[i]));
            cout << ans << " ";
    }
    cout << endl;
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int T;
    cin >> T;
    while (T--)
    {
        work();
    }
    return 0;
}
posted @   何太狼  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示