<牛客多校round 5>

Solved:3

rank:195

F. take

官方题解:小 A 在打开第 i 个箱子后会交换手中的钻石和第 i 个箱子中的钻石

当且仅当第 i个箱子的钻石是前 i 个箱子打开后出现的所有钻石里最大的。

那么要算概率的话,前面箱子中钻石大于等于它的打开后就不能有钻石
用树状数组维护一下

线段树(不会树状数组) 调了半天居然快速幂忘记写返回了

#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
using namespace std;
typedef long long ll;
const ll mod = 998244353;

ll sum[400005];
int num[100005];

ll pow_mod(ll x, ll y)
{
    ll res = 1;
    while(y)
    {
        if(y & 1) res = res * x % mod;
        y >>= 1;
        x = x * x % mod; 
    }
    return res;
}

struct node
{
    int p, d, id;
}E[100005];

bool cmp1(node A, node B)
{
    return A.d < B.d;    
} 

bool cmp2(node A, node B)
{
    return A.id < B.id;
}

void pushup(int rt)
{
    sum[rt] = sum[rt << 1] * sum[rt << 1 | 1] % mod;
}

void build(int l, int r, int rt)
{
    if(l == r)
    {
        sum[rt] = 1;
        return;
    }
    
    int m = l + r >> 1;
    build(l, m, rt << 1);
    build(m + 1, r , rt << 1 | 1);
    pushup(rt);
}

void update(int k, ll v, int l, int r, int rt)
{
    if(l == r)
    {
        sum[rt] = v;
        return;
    }
    
    int m = l + r >> 1;
    if(k <= m) update(k, v, l, m, rt << 1);
    else update(k, v, m + 1, r, rt << 1 | 1);
    pushup(rt);
}

ll query(int ql, int qr, int l, int r, int rt)
{
    if(ql <= l && qr >= r) return sum[rt];
    
    ll res = 1;
    int m = l + r >> 1;
    if(ql <= m) res = res * query(ql, qr, l, m, rt << 1) % mod;
    if(qr > m) res = res * query(ql, qr, m + 1, r, rt << 1 | 1) % mod;
    return res;
}

int main()
{
    int n;
    scanf("%d", &n);
    ll ny = pow_mod(100, mod - 2);    
    for(int i = 1; i <= n; i++)
    {
        scanf("%d%d", &E[i].p, &E[i].d);
        E[i].id = i;
        E[i].p = 100 - E[i].p;
    }
    sort(E + 1, E + 1 + n, cmp1);
    for(int i = 1; i <= n; i++) num[E[i].id] = i;
    sort(E + 1, E + 1 + n, cmp2);
    build(1, n, 1);
    
    ll ans = 0;
    for(int i = 1; i <= n; i++)
    {
        int v = num[E[i].id]; 
        ans = (ans + query(v, n, 1, n, 1) * (100 - E[i].p) % mod * ny % mod) % mod;
        update(v, E[i].p * ny % mod, 1, n, 1); 
    }
    printf("%lld\n", ans);
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/lwqq3/p/9415873.html