• loj2537 「PKUWC2018」Minimax 【概率 + 线段树合并】


    题目链接

    loj2537

    题解

    观察题目的式子似乎没有什么意义,我们考虑计算出每一种权值的概率
    先离散化一下权值
    显然可以设一个(dp),设(f[i][j])表示(i)节点权值为(j)的概率
    如果(i)是叶节点显然
    如果(i)只有一个儿子直接继承即可
    如果(i)有两个儿子,对于儿子(x),设另一个儿子为(y)
    则有

    [f[i][j] += f[x][j](1 - p_i)sumlimits_{k > j}f[r][k] + f[x][j]p_isumlimits_{k < j}f[r][k] ]

    直接转移是(O(n^2))的,发现每个节点都有(O(n))个位置需要转移
    考虑优化,可以考虑线段树合并

    对于一个子树中的权值(x),我们记另一棵子树比它大的概率为(maxa)
    (x)的概率要乘上(maxa(1 - p_i) + (1 - maxa)p_i = maxa + p_i - 2p_imaxa)

    所以我们在线段树合并过程中,优先合并右子树,并更新两棵子树的(maxa)(maxb),就可以在合并过程中转移了
    复杂度(O(nlogn))

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<map>
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define mp(a,b) make_pair<int,int>(a,b)
    #define cls(s) memset(s,0,sizeof(s))
    #define cp pair<int,int>
    #define LL long long int
    using namespace std;
    const int maxn = 300005,maxm = 8000005,INF = 1000000000,P = 998244353;
    inline int read(){
    	int out = 0,flag = 1; char c = getchar();
    	while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
    	while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
    	return out * flag;
    }
    int n,Ls[maxn],Rs[maxn],b[maxn],N,v10000;
    int rt[maxn],sum[maxm],ls[maxm],rs[maxm],tag[maxm],cnt;
    int p[maxn],maxa,maxb;
    inline int qpow(int a,int b){
    	int re = 1;
    	for (; b; b >>= 1,a = 1ll * a * a % P)
    		if (b & 1) re = 1ll * re * a % P;
    	return re;
    }
    inline void pd(int u){
    	if (tag[u] > 1){
    		sum[ls[u]] = 1ll * sum[ls[u]] * tag[u] % P;
    		sum[rs[u]] = 1ll * sum[rs[u]] * tag[u] % P;
    		tag[ls[u]] = 1ll * tag[ls[u]] * tag[u] % P;
    		tag[rs[u]] = 1ll * tag[rs[u]] * tag[u] % P;
    		tag[u] = 1;
    	}
    }
    void modify(int& u,int l,int r,int pos){
    	u = ++cnt; sum[u] = tag[u] = 1;
    	if (l == r) return;
    	int mid = l + r >> 1;
    	if (mid >= pos) modify(ls[u],l,mid,pos);
    	else modify(rs[u],mid + 1,r,pos);
    }
    int merge(int u,int v,int p){
    	if (!u && !v) return 0;
    	if (!u){
    		maxb = (maxb + sum[v]) % P;
    		int tmp;
    		tmp = (((maxa + p) % P - 2ll * p * maxa % P) % P + P) % P;
    		sum[v] = 1ll * sum[v] * tmp % P;
    		tag[v] = 1ll * tag[v] * tmp % P;
    		return v;
    	}
    	if (!v){
    		maxa = (maxa + sum[u]) % P;
    		int tmp;
    		tmp = (((maxb + p) % P - 2ll * p  * maxb % P) % P + P) % P;
    		sum[u] = 1ll * sum[u] * tmp % P;
    		tag[u] = 1ll * tag[u] * tmp % P;
    		return u;
    	}
    	pd(u); pd(v);
    	int t = ++cnt; tag[t] = 1;
    	rs[t] = merge(rs[u],rs[v],p);
    	ls[t] = merge(ls[u],ls[v],p);
    	sum[t] = (sum[ls[t]] + sum[rs[t]]) % P;
    	return t;
    }
    void dfs(int u){
    	if (!Ls[u]) modify(rt[u],1,N,p[u]);
    	else if (!Rs[u]) dfs(Ls[u]),rt[u] = rt[Ls[u]];
    	else {
    		dfs(Ls[u]); dfs(Rs[u]);
    		maxa = maxb = 0;
    		rt[u] = merge(rt[Ls[u]],rt[Rs[u]],p[u]);
    	}
    }
    int ans;
    void cal(int u,int l,int r){
    	if (l == r) {ans = (ans + 1ll * l * b[l] % P * sum[u] % P * sum[u] % P) % P;return;}
    	pd(u);
    	int mid = l + r >> 1;
    	cal(ls[u],l,mid);
    	cal(rs[u],mid + 1,r);
    }
    int main(){
    	n = read(); read(); int x; v10000 = qpow(10000,P - 2);
    	for (int i = 2; i <= n; i++){
    		x = read();
    		if (!Ls[x]) Ls[x] = i;
    		else Rs[x] = i;
    	}
    	for (int i = 1; i <= n; i++){
    		p[i] = read();
    		if (!Ls[i]) b[++N] = p[i];
    		else p[i] = 1ll * p[i] * v10000 % P;
    	}
    	sort(b + 1,b + 1 + N);
    	for (int i = 1; i <= n; i++)
    		if (!Ls[i]) p[i] = lower_bound(b + 1,b + 1 + N,p[i]) - b;
    	dfs(1);
    	cal(rt[1],1,N);
    	printf("%d
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    财富感悟:赚大钱的经典语录
    男人成为富翁必备五大特质
    上帝不会辜负每一个有梦的孩子(转)
    一百个绝佳句型
    欢迎光临腾飞品牌网和腾飞悬赏任务网
    金钱在哪里?财富就在你心里
    小本创业30条生意妙经
    告诉你钱途无量的六大创业领域
    告诉你一个简单、深刻的经商道理
    十二条创业经验:包你做梦都赚钱
  • 原文地址:https://www.cnblogs.com/Mychael/p/9215258.html
Copyright © 2020-2023  润新知