题目

题目描述
Vasya plays one very well-known and extremely popular MMORPG game. His game character has kk skill; currently the ii -th of them equals to a_{i}a
i

. Also this game has a common rating table in which the participants are ranked according to the product of all the skills of a hero in the descending order.

Vasya decided to ‘upgrade’ his character via the game store. This store offers nn possible ways to improve the hero’s skills; Each of these ways belongs to one of three types:

assign the ii -th skill to bb ;
add bb to the ii -th skill;
multiply the ii -th skill by bb .
Unfortunately, a) every improvement can only be used once; b) the money on Vasya’s card is enough only to purchase not more than mm of the nn improvements. Help Vasya to reach the highest ranking in the game. To do this tell Vasya which of improvements he has to purchase and in what order he should use them to make his rating become as high as possible. If there are several ways to achieve it, print any of them.

输入格式
The first line contains three numbers — k,n,mk,n,m ( 1<=k<=10^{5}1<=k<=10
5
, 0<=m<=n<=10^{5}0<=m<=n<=10
5
) — the number of skills, the number of improvements on sale and the number of them Vasya can afford.

The second line contains kk space-separated numbers a_{i}a
i

( 1<=a_{i}<=10^{6}1<=a
i

<=10
6
), the initial values of skills.

Next nn lines contain 33 space-separated numbers t_{j},i_{j},b_{j}t
j

,i
j

,b
j

( 1<=t_{j}<=3,1<=i_{j}<=k,1<=b_{j}<=10^{6}1<=t
j

<=3,1<=i
j

<=k,1<=b
j

<=10
6
) — the type of the jj -th improvement (1 for assigning, 2 for adding, 3 for multiplying), the skill to which it can be applied and the value of bb for this improvement.

输出格式
The first line should contain a number ll ( 0<=l<=m0<=l<=m ) — the number of improvements you should use.

The second line should contain ll distinct space-separated numbers v_{i}v
i

( 1<=v_{i}<=n1<=v
i

<=n ) — the indices of improvements in the order in which they should be applied. The improvements are numbered starting from 11 , in the order in which they appear in the input.

题意翻译
有 kk 个正整数 a_{1\dots k}a
1…k


有 nn 个操作,每个操作给定正整数 bb,有三种可能:将 a_ia
i

赋值为 bb,将 a_ia
i

加上 bb,将 a_ia
i

乘以 bb。
你可以从 nn 个操作中选择最多 mm 个操作,并按照一定顺序执行。
你的目标是最大化 \prod_{i=1}^k a_i∏
i=1
k

a
i

的值。
k,n \le 10^5k,n≤10
5

输入输出样例
输入 #1复制
2 4 3
13 20
1 1 14
1 2 30
2 1 6
3 2 2
输出 #1复制
3
2 3 4

思路

首先如果确定了执行的操作,执行顺序一定为赋值、加、乘。赋值操作只保留最大的,并可以转化为加法。每个数的加法操作按从大到小顺序排序后可以转化为乘法。最后将所有乘法操作从大到小排序选前 m个即可。

代码

const int N = 1e5 + 7;
int n, m, k, s;
ui t[N];
ll a[N], b;
pair <ll, int> v1[N];
vector <pair <ll, int> > v2[N], v3;
pq <pair <ld, int> > q;
vi ans;

void print() {
    for (int i = 1; i <= k; i++) {
        for (ui j = 0; j < t[i]; j++)
            if (v2[i][j].se < 0) ans.pb(-v2[i][j].se);
        for (ui j = 0; j < t[i]; j++)
            if (v2[i][j].se > 0) ans.pb(v2[i][j].se);
    }
    while (v3.size()) ans.pb(v3.back().se), v3.pop_back();
    print(ans.size());
    for (auto x : ans) print(x, ' ');
}

void get(int x) {
    if (t[x] < v2[x].size())
        q.push(mp(1.0L * v2[x][t[x]++].fi / a[x], x));
}

int main() {
    rd(k), rd(n), rd(m);
    for (int i = 1; i <= k; i++) rd(a[i]);
    for (int i = 1, o, x; i <= n; i++) {
        rd(o), rd(x), rd(b);
        if (o == 1) v1[x] = max(v1[x], mp(b, i));
        if (o == 2) v2[x].pb(mp(b, i));
        if (o == 3) v3.pb(mp(b, i));
    }
    for (int i = 1; i <= k; i++) {
        if (v1[i].fi > a[i])
            v2[i].pb(mp(v1[i].fi - a[i], -v1[i].se));
        sort(v2[i].begin(), v2[i].end());
        reverse(v2[i].begin(), v2[i].end());
        s += v2[i].size();
    }
    sort(v3.begin(), v3.end());
    reverse(v3.begin(), v3.end());
    while ((int)v3.size() > m) v3.pop_back();
    if (s + (int)v3.size() <= m) {
        for (int i = 1; i <= k; i++) t[i] = v2[i].size();
        return print(), 0;
    }
    for (int i = 1; i <= k; i++) get(i);
    for (int i = v3.size(); i < m; i++) {
        int x = q.top().se;
        q.pop(), a[x] += v2[x][t[x]-1].fi, get(x);
    }
    while (v3.size()) {
        int x = q.top().se;
        ll b1 = v2[x][t[x]-1].fi, b2 = v3.back().fi;
        if (b1 <= a[x] * (b2 - 1)) break;
        q.pop(), v3.pop_back(), a[x] += b1, get(x);
    }
    while (q.size()) {
        int x = q.top().se;
        q.pop(), --t[x];
    }
    return print(), 0;
}