pkusc 快到了……做点题涨涨 rp。

初见时 yy 了一个类似于归并的东西,\(O(n^2)\),50 分。

50 分 yy 做法

对于一个点,枚举他能到达的权值(假设这个权值在左子树,在右子树是一样的),选上这个点的概率就是“在左子树选上这个点的概率 \(\times\) (选择子结点最大值的概率 \(\times\) 右子树选出比这个点小的点的概率和+选择子结点最小值的概率 \(\times\) 右子树选出比这个点大的点的概率和)”。

100 分

我们发现,瓶颈在于合并。我们先想到启发式合并,然后就不会了。

我们又想到线段树合并。这里就参考ref这里就可以了。

#include <algorithm>
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
int n, uu, num[300005], bb, rot[300005], tot, maxa, maxb, ans;
const int mod=998244353;
struct Node{
int l, r, v;
}nd[300005];
struct SGTNode{
int l, r, v, t;
}sgt[5000005];
int ksm(int a, int b){
int re=1;
while(b){
if(b&1) re = (ll)re * a % mod;
a = (ll)a * a % mod;
b >>= 1;
}
return re;
}
void insert(int &x, int l, int r, int v){
x = ++tot;
sgt[x].v = sgt[x].t = 1;
if(l==r) ;
else{
int mid=(l+r)>>1;
if(v<=mid) insert(sgt[x].l, l, mid, v);
else insert(sgt[x].r, mid+1, r, v);
}
}
void pushDown(int x){
if(!x || sgt[x].t<=1) return ;
sgt[sgt[x].l].t = (ll)sgt[sgt[x].l].t * sgt[x].t % mod;
sgt[sgt[x].r].t = (ll)sgt[sgt[x].r].t * sgt[x].t % mod;
sgt[x].v = (ll)sgt[x].v * sgt[x].t % mod;
sgt[x].t = 1;
}
int merge(int x, int y, int p){
if(!x && !y) return 0;
pushDown(x); pushDown(y);
if(!y){
maxa = (maxa + sgt[x].v) % mod;
sgt[x].t = ((maxb+p)%mod-(ll)2*maxb*p%mod+mod) % mod;
pushDown(x);
return x;
}
if(!x){
maxb = (maxb + sgt[y].v) % mod;
sgt[y].t = ((maxa+p)%mod-(ll)2*maxa*p%mod+mod) % mod;
pushDown(y);
return y;
}
sgt[x].r = merge(sgt[x].r, sgt[y].r, p);
sgt[x].l = merge(sgt[x].l, sgt[y].l, p);
sgt[x].v = (sgt[sgt[x].l].v + sgt[sgt[x].r].v) % mod;
return x;
}
void dfs(int x){
if(!nd[x].l)
insert(rot[x], 1, bb, nd[x].v);
else if(!nd[x].r){
dfs(nd[x].l);
rot[x] = rot[nd[x].l];
}
else{
dfs(nd[x].l);
dfs(nd[x].r);
maxa = maxb = 0;
rot[x] = merge(rot[nd[x].l], rot[nd[x].r], nd[x].v);
}
}
void getAns(int x, int l, int r){
if(!x) return ;
pushDown(x);
if(l==r)
ans = (ans + (ll)l*num[l]%mod*sgt[x].v%mod*sgt[x].v%mod) % mod;
else{
int mid=(l+r)>>1;
getAns(sgt[x].l, l, mid);
getAns(sgt[x].r, mid+1, r);
}
}
int main(){
cin>>n;
for(int i=1; i<=n; i++){
scanf("%d", &uu);
if(nd[uu].l) nd[uu].r = i;
else nd[uu].l = i;
}
int inv=ksm(10000, mod-2);
for(int i=1; i<=n; i++){
scanf("%d", &uu);
if(nd[i].l) nd[i].v = (ll)uu * inv % mod;
else{
nd[i].v = uu;
num[++bb] = uu;
}
}
sort(num+1, num+1+bb);
bb = unique(num+1, num+1+bb) - (num + 1);
for(int i=1; i<=n; i++)
if(!nd[i].l)
nd[i].v = lower_bound(num+1, num+1+bb, nd[i].v) - num;
dfs(1);
getAns(rot[1], 1, bb);
cout<<ans<<endl;
return 0;
}

loj2537 「PKUWC 2018」Minimax的更多相关文章

  1. LOJ #2537. 「PKUWC 2018」Minimax (线段树合并 优化dp)

    题意 小 \(C\) 有一棵 \(n\) 个结点的有根树,根是 \(1\) 号结点,且每个结点最多有两个子结点. 定义结点 \(x\) 的权值为: 1.若 \(x\) 没有子结点,那么它的权值会在输入 ...

  2. 「PKUWC 2018」Minimax

    传送门:Here 一道线段树合并好题 如果要维护点$ x$的信息,相当于合并$ x$的两棵子树 对于这题显然有:任何叶子节点的权值都可能出现在其祖先上 因而我们只需要在线段树合并的时候维护概率即可 我 ...

  3. LOJ #2542. 「PKUWC 2018」随机游走(最值反演 + 树上期望dp + FMT)

    写在这道题前面 : 网上的一些题解都不讲那个系数是怎么推得真的不良心 TAT (不是每个人都有那么厉害啊 , 我好菜啊) 而且 LOJ 过的代码千篇一律 ... 那个系数根本看不出来是什么啊 TAT ...

  4. LOJ #2541. 「PKUWC 2018」猎人杀(容斥 , 期望dp , NTT优化)

    题意 LOJ #2541. 「PKUWC 2018」猎人杀 题解 一道及其巧妙的题 , 参考了一下这位大佬的博客 ... 令 \(\displaystyle A = \sum_{i=1}^{n} w_ ...

  5. LOJ #2540. 「PKUWC 2018」随机算法(概率dp)

    题意 LOJ #2540. 「PKUWC 2018」随机算法 题解 朴素的就是 \(O(n3^n)\) dp 写了一下有 \(50pts\) ... 大概就是每个点有三个状态 , 考虑了但不在独立集中 ...

  6. LOJ #2538. 「PKUWC 2018」Slay the Spire (期望dp)

    Update on 1.5 学了 zhou888 的写法,真是又短又快. 并且空间是 \(O(n)\) 的,速度十分优秀. 题意 LOJ #2538. 「PKUWC 2018」Slay the Spi ...

  7. loj2538 「PKUWC 2018」Slay the Spire

    pkusc 快到了--做点题涨涨 rp. ref我好菜啊QAQ. 可以发现期望只是一个幌子.我们的目的是:对于所有随机的选择方法(一共 \(\binom{2n}{m}\)种),这些选择方法都最优地打出 ...

  8. loj2540 「PKUWC 2018」随机算法

    pkusc 快到了--做点题涨涨 rp. 记 \(f(S,i)\) 表示 \(S\) 这个集合是决计不能选的(要么属于独立集,要么和独立集相连),或称已经考虑了的,\(i\) 表示此集合对应的最大独立 ...

  9. 「PKUWC 2018」随机算法 (第二版,正解做法)

    上一版貌似是打了 O(3 ^ N) 暴力和 一条链的情况,得了60分.... 第一次做的时候光想练一练暴力...就没去想正解,谁知道正解比暴力好写不知道多少,mmp 设 f(S) 为 选集合S中的点可 ...

随机推荐

  1. DRF之视图组件

    不断的优化我们写的程序,是每个程序员必备的技能和职业素养,也是帮助我们成长的非常重要的手段. 使用serializer进行put接口设计 根据规范,PUT接口用来定义用户对数据修改的逻辑,也就是upd ...

  2. poj3334(Connected Gheeves)

    Connected Gheeves Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 1008   Accepted: 368 ...

  3. [SVN]TortoiseSVN报“500 Internal Server Error”错误的解决方法

    背景:由于某种原因,本人重启了一下SVN服务的物理机,重启过后发现所有人访问SVN都报如下错误. 由于重启之前是没有做过任何改动,所以面对这个错误有点摸不着头脑,防火墙.网管.清缓存等方法都试过,还没 ...

  4. Check-Point-Security-Gateway-BYOL-R77.30-041.161

    平台: CentOS 类型: 虚拟机镜像 软件包: checkpoint redhat smartconsole basic software security vfw 服务优惠价: 按服务商许可协议 ...

  5. cmd中不能输入中文

    在命令行窗口下不能输入中文,只能输入英文,这是因为cmd.exe窗口启动时并没有启动conime.exe进程.事实上,这个进程容易被后门病毒利用,因此网上很多人都把它当成病毒看待,一些网上下载的系统就 ...

  6. libav(ffmpeg)简明教程(1)

    突然发现又有好久没有写技术blog了,主要原因是最近时间都用来研究libav去了(因为api极类似ffmpeg,虽然出自同一份代码的另外一个分支,因项目选用libav,故下文均用libav代替),其实 ...

  7. spark 之knn算法

    好长时间忙的没写博客了.看到有人问spark的knn,想着做推荐入门总用的knn算法,顺便写篇博客. 作者:R星月  http://www.cnblogs.com/rxingyue/p/6182526 ...

  8. C语言异常处理编程的三个境界

    http://blog.csdn.net/treefish2012/article/details/17466487 这是上一次看完Herb Sutter的<Exceptional C++> ...

  9. javascript中Array常用方法

    一.基本概念 1.什么是数组 数组就是一组数据的集合 其表现形式就是内存中的一段连续的内存地址 数组名称其实就是连续内存地址的首地址 2.关于js中的数组特点 数组定义时无需指定数据类型 数组定义时可 ...

  10. PS 厘米与像素切换

    方法一: 快捷键 ctrl + r   打开标尺将鼠标放在标尺刻度上右键 出现菜单里修改即可: 方法二: 编辑---首选项---单位与标尺 修改即可: