牛客多校第五场----F take

链接:https://www.nowcoder.com/acm/contest/143/F
来源:牛客网

take
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
Kanade has n boxes , the i-th box has p[i] probability to have an diamond of d[i] size.

At the beginning , Kanade has a diamond of 0 size. She will open the boxes from 1-st to n-th. When she open a box,if there is a diamond in it and it’s bigger than the diamond of her , she will replace it with her diamond.

Now you need to calculate the expect number of replacements.

You only need to output the answer module 998244353.

Notice: If x%998244353=y*d %998244353 ,then we denote that x/y%998244353 =d%998244353

输入描述:
The first line has one integer n.

Then there are n lines. each line has two integers p[i]*100 and d[i].
输出描述:
Output the answer module 998244353
示例1
输入
复制
3
50 1
50 2
50 3
输出
复制
499122178
备注:
1<= n <= 100000

1<=p[i]*100 <=100

1<=d[i]<=10^9

注意:树状数组的下标必须从1开始,,因为lowbit(0)=0,如果从0开始的话就会陷入死循环!!树状数组适用于所有满足结合律的运算(加法,乘法,异或等)

所有树状数组能完成的操作线段树都能够完成,但是线段树的代码复杂,时间复杂度也比较高,查询、修改需要递归完成,而,树状数组的操作不仅代码简洁,便于理解,而且一切都是递推完成的,所以能用树状数组解决的问题尽量不要用线段树来写。

网上找的题解:
这里写图片描述

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const LL mod = 998244353;
const int N = 100005;
typedef struct Node{
    int d,pos;
    LL p;
}Node;
Node node[N];
LL tree[N];
int n;

bool cmp(const Node &p,const Node &q)
{
    if(p.d == q.d){
        return p.pos > q.pos;
    }
    else{
        return p.d > q.d;
    }
}
LL pow_mod(LL x,LL y){
    LL ans = 1;
    while(y){
        if(y & 1) ans = (ans * x) % mod;
        x = (x * x) % mod;
        y /= 2;
    }
    return ans;
}

void add(int k,LL num)//修改值
{
    while(k <= n)
    {
        tree[k] = (tree[k] * num) % mod;
        k+=k&-k;
    }
}

LL read(int k)//求区间乘
{
    LL sum = 1;
    while(k)
    {
        sum = (sum * tree[k]) % mod;
        k-=k&-k;
    }
    return sum;
}



int main()
{
    LL inv100 = pow_mod(100LL,mod - 2);
    while(~scanf("%d",&n))
    {

        for(int i = 0;i < n;++i)
        {
            scanf("%lld %d",&node[i].p,&node[i].d);
            node[i].p = (node[i].p * inv100) % mod;
            node[i].pos = i + 1;
        }
        sort(node,node + n,cmp);
        fill(tree,tree + N,1);
        //printf("%d\n",tree[0]);
        LL ans = 0;
        for(int i = 0;i < n;++i)
        {
            ans = (ans + (1LL * node[i].p * read(node[i].pos - 1))% mod) % mod;
            add(node[i].pos,(1 - node[i].p + mod) % mod);
        }
        printf("%lld\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36386435/article/details/81380923