Codeforces Round 935 (Div. 3) F. Kirill and Mushrooms(主席树求区间第k大值)

As soon as everyone in the camp fell asleep, Kirill sneaked out of the tent and went to the Wise Oak to gather mushrooms.

It is known that there are n n n mushrooms growing under the Oak, each of which has magic power v i v_i vi. Kirill really wants to make a magical elixir of maximum strength from the mushrooms.

The strength of the elixir is equal to the product of the number of mushrooms in it and the minimum magic power among these mushrooms. To prepare the elixir, Kirill will sequentially pick one mushroom growing under the Oak. Kirill can gather mushrooms in any order.

However, it’s not that simple. The Wise Oak informed Kirill of a permutation of numbers p p p from 1 1 1 to n n n. If Kirill picks only k k k mushrooms, then the magic power of all mushrooms with indices p 1 , p 2 , … , p k − 1 p_1, p_2, \dots, p_{k - 1} p1,p2,,pk1 will become 0 0 0. Kirill will not use mushrooms with zero magic power to prepare the elixir.

Your task is to help Kirill gather mushrooms in such a way that he can brew the elixir of maximum possible strength. However, Kirill is a little scared to stay near the oak for too long, so out of all the suitable options for gathering mushrooms, he asks you to find the one with the minimum number of mushrooms.

A permutation of length n n n is an array consisting of n n n different integers from 1 1 1 to n n n in any order. For example, [ 2 , 3 , 1 , 5 , 4 ] [2,3,1,5,4] [2,3,1,5,4] is a permutation, but [ 1 , 2 , 2 ] [1,2,2] [1,2,2] is not a permutation ( 2 2 2 appears in the array twice) and [ 1 , 3 , 4 ] [1,3,4] [1,3,4] is also not a permutation ( n = 3 n=3 n=3, but 4 4 4 appears in the array).

Input

Each test consists of multiple test cases. The first line contains a single integer t t t ( 1 ≤ t ≤ 1 0 4 1 \le t \le 10^4 1t104) — the number of test cases. The description of the test cases follows.

The first line of each test case contains a single integer n n n ( 1 ≤ n ≤ 200   000 1 \le n \le 200\,000 1n200000) — the number of mushrooms.

The second line contains an array v v v of size n n n ( 1 ≤ v i ≤ 1 0 9 1\le v_i \le 10^9 1vi109) — the magic powers of the mushrooms.

The third line contains a permutation p p p of numbers from 1 1 1 to n n n.

It is guaranteed that the sum of the values of n n n over all test cases does not exceed 2 ⋅ 1 0 5 2\cdot 10^5 2105.
Output

For each test case, output two integers separated by a space — the maximum strength of the elixir that can be brewed and the minimum number of mushrooms that Kirill needs to use for this.
Example
input

6
3
9 8 14
3 2 1
5
1 2 3 4 5
1 2 3 4 5
6
1 2 3 4 5 6
6 5 4 3 2 1
5
1 4 6 10 10
2 1 4 5 3
4
2 2 5 5
4 2 3 1
5
1 2 9 10 10
1 4 2 3 5

output

6
3
9 8 14
3 2 1
5
1 2 3 4 5
1 2 3 4 5
6
1 2 3 4 5 6
6 5 4 3 2 1
5
1 4 6 10 10
2 1 4 5 3
4
2 2 5 5
4 2 3 1
5
1 2 9 10 10
1 4 2 3 5

Note

In the first example, you need to take the mushrooms with indices 1 1 1 and 2 2 2, so the strength of the elixir is equal to 2 ⋅ min ⁡ ( a 1 , a 2 ) = 2 ⋅ min ⁡ ( 9 , 8 ) = 2 ⋅ 8 = 16 2 \cdot \min(a_1, a_2) = 2 \cdot \min(9, 8) = 2 \cdot 8 = 16 2min(a1,a2)=2min(9,8)=28=16. Note that the magic power of the mushroom with index 3 3 3 after picking two mushrooms will become 0 0 0.

大体题意
长度为 n n n 的序列 v v v,以及一个长度为 n n n 的序列 p p p ,当取序列 v v v k k k 个数时要保证这 k k k 个数不属于 p 1 , . . . , k − 1 p_{1,...,k-1} p1,...,k1 。对于长度为 k k k 的序列 a [ 1 − k ] , ∀ ( i , j ) , 1 ≤ i < j ≤ k   a n d   a i ! = a j   a n d   a i , a j ∉ p a[1-k],\forall(i,j),1\le i < j \le k\ and\ a_i!=a_j\ and\ a_i,a_j\notin p a[1k],(i,j),1i<jk and ai!=aj and ai,aj/p,其权值为 m i n { v a i } × k min\{v_{a_i}\} \times k min{vai}×k,求出权值最大的序列权值及其序列长度 k k k

思路分析
首先我们很容易想到,当我们选 k k k 个数时,我们能找到的序列一定从 a p k , . . . , n a_{p_{k,...,n}} apk,...,n中选到,那我们不妨将序列直接按照 p p p 序列排一下序;

vector<int> p(n + 10), v(n + 10), a(n + 10);
for (int i = 1; i <= n; i++)
    a[i] = v[p[i]];

由此我们很容易想到的是要是权值最大,当我们要取 k k k 个数时,我们一定是取当前可以取出当前可取数之中最大的前 k k k 个数,也就是说我们只要找到序列 a a a 对应的可取区间 [ k , n ] [k,n] [k,n] 中的第 k k k 大值并 ×   k \times\ k × k,即得此时权值的最大值,因此我们只需枚举一下 k k k 即得答案(注意 k k k 的取值范围是 [   1   ,   ⌈ n 2 ⌉   ] [\ 1\ ,\ \lceil \frac{n}{2} \rceil\ ] [ 1 , 2n ])。

代码

#include <bits/stdc++.h>
using namespace std;

#define all(x) x.begin(), x.end()
#define bit1(x) __builtin_popcount(x)
#define Pqueue priority_queue
#define lc p << 1
#define rc p << 1 | 1
#define IOS ios::sync_with_stdio(false), cin.tie(0);
#define fi first
#define se second

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<ll, ll> PII;

const ll mod = 1000000007;
const ll N = 1e6 + 10;
const ld eps = 1e-9;
const ll inf = 1e18;
const ll P = 131;
const ll dir[8][2] = {1, 0, 0, 1, -1, 0, 0, -1, 1, 1, 1, -1, -1, 1, -1, -1};

struct Tree
{
    int l, r, sum;
} tr[N << 4];
int root[N], idx;

void insert(int &p, int t, int l, int r, int k)
{
    p = ++idx;
    tr[p] = tr[t];
    tr[p].sum = tr[t].sum + 1;
    if (l == r)
        return;
    int mid = l + r >> 1;
    if (k <= mid)
        insert(tr[p].l, tr[t].l, l, mid, k);
    else
        insert(tr[p].r, tr[t].r, mid + 1, r, k);
}
int query(int p, int t, int l, int r, int k)
{
    if (l == r)
        return l;
    int mid = l + r >> 1;
    int s = tr[tr[p].l].sum - tr[tr[t].l].sum;
    if (k <= s)
        return query(tr[p].l, tr[t].l, l, mid, k);
    return query(tr[p].r, tr[t].r, mid + 1, r, k - s);
}

void solve()
{
    idx = 0;
    int n;
    cin >> n;
    vector<int> a(n + 10), b(n + 10), c(n + 1);
    for (int i = 1; i <= n; i++)
        cin >> a[i], c[i] = a[i];
    for (int i = 1; i <= n; i++)
        cin >> b[i];
    vector<int> p(n + 10);
    for (int i = 1; i <= n; i++)
        p[i] = a[b[i]];
    sort(all(c));
    c.erase(unique(all(c)), c.end());
    int len = c.size() - 1;
    // cout << ":::";
    // for (int i = 1; i <= n; i++)
    //     cout << p[i] << " \n"[i == n];
    for (int i = 1; i <= n; i++)
    {
        int k = lower_bound(all(c), p[i]) - c.begin();
        insert(root[i], root[i - 1], 1, len, k);
    }
    ll mx = 0, mx_i = 0;
    for (int i = 1; i <= (n + 1) / 2; i++)
    {
        int k = n - (i - 1) * 2;
        int pos = query(root[n], root[i - 1], 1, len, k);
        // cout << c[pos] << " ";
        if (mx < 1ll * i * c[pos])
        {
            mx = 1ll * i * c[pos];
            mx_i = i;
        }
    }
    cout << mx << " " << mx_i << "\n";
}

int main()
{
    IOS int T = 1;
    cin >> T;
    while (T--)
        solve();
    return 0;
}

/*
oxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxox
x                                                                                      o
o       _/_/_/_/                                                              _/       x
x      _/                                                                              o
o     _/_/_/_/ _/  _/_/   _/_/   _/_/_/ _/_/   _/_/_/     _/_/    _/_/_/    _/ _/   _/ x
x    _/       _/_/     _/    _/ _/   _/   _/  _/    _/ _/    _/  _/    _/  _/   _/ _/  o
o   _/       _/       _/    _/ _/   _/   _/  _/    _/ _/    _/  _/    _/  _/    _/_/   x
x  _/       _/         _/_/   _/   _/   _/  _/_/_/     _/_/ _/ _/    _/  _/      _/    o
o                                          _/                           _/      _/     x
x                                         _/                        _/_/       _/      o
o                                                                                      x
xoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxo
*/```

 
  • 9
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Codeforces Round 894 (Div. 3) 是一个Codeforces举办的比赛,是第894轮的Div. 3级别比赛。它包含了一系列题目,其中包括题目E. Kolya and Movie Theatre。 根据题目描述,E. Kolya and Movie Theatre问题要求我们给定两个字符串,通过三种操作来让字符串a等于字符串b。这三种操作分别为:交换a中相同位置的字符、交换a中对称位置的字符、交换b中对称位置的字符。我们需要先进行一次预处理,替换a中的字符,然后进行上述三种操作,最终得到a等于b的结果。我们需要计算预处理操作的次数。 根据引用的讨论,当且仅当b[i]==b[n-i-1]时,如果a[i]!=a[n-i-1],需要进行一次操作;否则不需要操作。所以我们可以遍历字符串b的前半部分,判断对应位置的字符是否与后半部分对称,并统计需要进行操作的次数。 以上就是Codeforces Round 894 (Div. 3)的简要说明和题目E. Kolya and Movie Theatre的要求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Codeforces Round #498 (Div. 3) (A+B+C+D+E+F)](https://blog.csdn.net/qq_46030630/article/details/108804114)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Codeforces Round 894 (Div. 3)A~E题解](https://blog.csdn.net/gyeolhada/article/details/132491891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

panjyash

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值