2018.11.01-dtoj-4020-式神守护(yukari)———关于错排
题目描述:
幽幽子站在西行妖下,她需要解封西行妖最后的力量。
西行妖可以当作一个有n 个点的树,每个点都有一些符文,初始每个点符文个数为1。
幽幽子可以施展魔法,将符文随机移动,来解封封印。
每个点上的符文可以看作是一个1~m 的排列,原本的状态为1,2,3,4,……,m 按顺序排列
(m 为符文的个数)。想要解封一个点上的封印,要求排列中对于任意的i, p i i 。幽幽子
每次的魔法效果是随机形成一个排列,尝试能否解除封印。
幽幽子每次会走过一条路径,从s 到t,对每个点施展一次魔法,并询问能解封的点的
期望个数。
现在有Q 次操作:
Add s t x 在s 到t 的路径上每个点加x 个新的符文。
Multi s t x 在s 到t 的路径上,每个点符文个数*x。
Query s t 求从s 到t 解封点的期望个数是多少。
(注意:每次Query 操作是独立的,即前一次Query 中施展的魔法在Query 结束时被立
即撤销,所有走过的路径上点的符文排列变为p i i ,对后续操作不产生影响)
输入:
第一行一个数n,表示树的点数。
下面n-1 行,每行两个数u,v,表示有一条边连接u 和v。
下面一行一个Q,表示操作次数。
下面Q 行,每行一个操作:
Add s t x 在s 到t 的路径上每个点加x 个符文。
Multi s t x 在s 到t 的路径上,每个点符文个数*x。
Query s t 求从s 到t 解封点的期望个数是多少。
输出:
对于每次询问Query,输出一行一个实数(为了避免卡精度,所以只需要保留1 位小数),
表示解封点的期望个数。
数据范围:
n,m≤8*104
算法标签:树链剖分
小延伸——关于错排:
错排的递推式子:
D(n)=(D(n-1)+D(n-2))*(n-1)
因为你每次可以选择从n-1个已经满足错拍的排列中选择任意一个数与当前新加入的数进行交换,或者从n-2的已经满足的排列中,选择一个本在原位的数字的新加入的数字交换位置。
思路:
打表或者感性认知发现,当字符的序列达到一定长度后单个数字的贡献会逐渐接近一个数,且修改操作除了*1特判,其他必然增大,计算发现精度范围内增大仍有变化的分界点大概是20,因此操作的时候一旦字符长度高于20,我们就不再进行操作,因此每个数至多被修改20次,效率可观。区间操作用树剖维护。
以下代码:
#include<bits/stdc++.h> #define il inline #define D double #define _(d) while(d(isdigit(ch=getchar()))) using namespace std; const int N=8e4+5; char s[10]; D kk[N],jc[N],sum[N<<2]; int n; int head[N],ne[N<<1],to[N<<1],cnt; int fa[N],d[N],sz[N],son[N],top[N],dfn[N],tot,minn[N<<2]; il int read(){int x,f=1;char ch;_(!)ch=='-'?f=-1:f;x=ch^48;_()x=(x<<1)+(x<<3)+(ch^48);return f*x;} il void insert(int x,int y){ne[++cnt]=head[x];head[x]=cnt;to[cnt]=y;} void dfs1(int x){sz[x]=1;int maxn=-1;for(int i=head[x];i;i=ne[i]){if(fa[x]==to[i])continue;d[to[i]]=d[x]+1;fa[to[i]]=x;dfs1(to[i]);sz[x]+=sz[to[i]];if(maxn<sz[to[i]])maxn=sz[to[i]],son[x]=to[i];} } void dfs2(int x,int rt){dfn[x]=++tot;top[x]=rt;if(!son[x])return;dfs2(son[x],rt);for(int i=head[x];i;i=ne[i]){if(dfn[to[i]])continue;dfs2(to[i],to[i]);} } il void update(int x){minn[x]=min(minn[x<<1],minn[x<<1|1]);sum[x]=sum[x<<1]+sum[x<<1|1]; } il D Iq(int x,int l,int r,int ql,int qr){if(ql<=l&&r<=qr)return sum[x];int mid=(l+r)>>1;D res=0.0;if(ql<=mid)res+=Iq(x<<1,l,mid,ql,qr);if(mid<qr)res+=Iq(x<<1|1,mid+1,r,ql,qr);return res; } il D Tq(int x,int y){D res=0.0;while(top[x]!=top[y]){if(d[top[x]]<d[top[y]])swap(x,y);res+=Iq(1,1,n,dfn[top[x]],dfn[x]);x=fa[top[x]];}if(d[x]>d[y])swap(x,y);res+=Iq(1,1,n,dfn[x],dfn[y]);return res; } void Ia(int x,int l,int r,int ql,int qr,int v){if(minn[x]>=20)return;if(l==r){minn[x]+=v;if(minn[x]>20)sum[x]=kk[20];else sum[x]=kk[minn[x]];return;}int mid=(l+r)>>1;if(ql<=mid)Ia(x<<1,l,mid,ql,qr,v);if(mid<qr)Ia(x<<1|1,mid+1,r,ql,qr,v);update(x); } il void Ta(int x,int y,int v){while(top[x]!=top[y]){if(d[top[x]]<d[top[y]])swap(x,y);Ia(1,1,n,dfn[top[x]],dfn[x],v);x=fa[top[x]];}if(d[x]>d[y])swap(x,y);Ia(1,1,n,dfn[x],dfn[y],v); } void Im(int x,int l,int r,int ql,int qr,int v){if(minn[x]>=20)return;if(l==r){minn[x]*=v;if(minn[x]>20)sum[x]=kk[20];else sum[x]=kk[minn[x]];return;}int mid=(l+r)>>1;if(ql<=mid)Im(x<<1,l,mid,ql,qr,v);if(mid<qr)Im(x<<1|1,mid+1,r,ql,qr,v);update(x); } il void Tm(int x,int y,int v){while(top[x]!=top[y]){if(d[top[x]]<d[top[y]])swap(x,y);Im(1,1,n,dfn[top[x]],dfn[x],v);x=fa[top[x]];}if(d[x]>d[y])swap(x,y);Im(1,1,n,dfn[x],dfn[y],v); } void build(int x,int l,int r){if(l==r){minn[x]=1;return;}int mid=(l+r)>>1;build(x<<1,l,mid);build(x<<1|1,mid+1,r);update(x); } int main() {n=read();for(int i=1;i<n;i++){int x=read(),y=read();insert(x,y);insert(y,x);}d[1]=1;dfs1(1);dfs2(1,1);kk[0]=1.0;kk[1]=0.0;for(int i=2;i<=20;i++)kk[i]=(D)(i-1)*(kk[i-1]+kk[i-2]);jc[0]=1;for(int i=1;i<=20;i++)jc[i]=jc[i-1]*(D)i;for(int i=1;i<=20;i++)kk[i]=kk[i]/jc[i];build(1,1,n);int Q=read();while(Q--){scanf(" %s",&s);int x=read(),y=read();if(s[0]=='A'){int k=read();Ta(x,y,k);}else if(s[0]=='M'){int k=read();if(k!=1)Tm(x,y,k);}else if(s[0]=='Q'){printf("%.1lf\n",Tq(x,y));}}return 0; }
View Code
转载于:https://www.cnblogs.com/Jessie-/p/9888772.html
2018.11.01-dtoj-4020-式神守护(yukari)———关于错排相关推荐
- 前端面试题目汇总摘录(JS 基础篇 —— 2018.11.01更新)
温故而知新,保持空杯心态 JS 基础 JavaScript 的 typeof 返回那些数据类型 object number function boolean undefined string type ...
- 2018.11.01 NOIP训练 cost数(搜索+容斥原理)
传送门 唉考试的时候忘记剪倍数的枝了666666分滚粗. 其实就是一直取lcmlcmlcm搜索,然后容斥原理统计就行了. 代码 转载于:https://www.cnblogs.com/ldxcaica ...
- 2018.11.01【NOIP2016】【洛谷P2831】愤怒的小鸟(状压DP)
传送门 解析: 数据范围181818,多么显然的状压... 但是!!!为什么O(n22n)O(n^22^n)O(n22n)能过???复杂度明显不对啊... 这里提供一种O(n2n)O(n2^n)O(n ...
- 编程实现一个比较任意两个软件版本号大小的函数 2018.11.01(更新)
如 1.2.3a 和 1.2.4b 我写的方法,各位大大还有啥好的办法留言一下. /*** 这是个错误的方法,错误的错误的错误的错误的,某次面试面试官看我的博客说这个方法有问题,我回来思考了一下确实有 ...
- Noip 模拟 14 2018/11/1
T1:白玉楼前(youmu) 妖梦现在要玩幽幽子的游戏,她才能拿回自己的半灵. 游戏规则是这样的: 幽幽子有 n 个点,现在她让妖梦对每个点随机一条出边 (随机到每个点的概率都相等),然后得到一张图. ...
- 平安京服务器维护无法发布新内容,阴阳师4月17日更新维护 式神不知火重磅降临...
阴阳师4月17日更新维护,SSR阶式神不知火重磅降临,SP/SSR概率翻升!回馈阴阳师大人召唤福利五重奏,接下来就来一起看看阴阳师4月17日更新维护的具体内容吧. 亲爱的阴阳师大人: 为了给大家带来更 ...
- QIIME 2用户文档. 10元数据Metadata(2018.11)
文章目录 前情提要 QIIME 2用户文档. 9元数据 元数据格式要求 元数据验证 前导和尾随空格字符 注释和空行 标识符列 标识符的建议 元数据列 列类型 数字格式化 高级文件格式详细信息 TSV方 ...
- QIIME 2用户文档. 7差异丰度分析gneiss(2018.11)
文章目录 前情提要 QIIME 2用户文档. 7差异丰度分析gneiss 创建`balances` 选项1:相关性聚类 选项2:梯度聚类 用平衡建立线性模型 Reference 译者简介 猜你喜欢 写 ...
- IDEA 2018 激活 IDEA 2018.3激活教程 最新的(三种)—2018.11.26亲测
https://blog.csdn.net/HALEN001/article/details/81137092 IntelliJ IDEA 2018.3(Ultimate Edition)激活方法 本 ...
- Haproxy(三)详细记录 2018年01月05日 16:47:36
Haproxy(三)详细记录 2018年01月05日 16:47:36 阅读数:361 一.各种负载均衡 1.1 tcp反向代理 tcp 22端口反向代理: # vim /etc/haproxy/ha ...
最新文章
- vscode 配置 Latex 编译后自动清理多余文件(.log .out等文件)
- PMCAFF出品|十一月30篇爆款文章合集,干货、技能、内涵齐飞,总有一款适合你
- OpenGL反射和折射
- 395. Longest Substring with At Least K Repeating Characters
- 微软发布新的 Azure Pipelines 功能和集成
- SQLite | 数据库设计与 Creat Table 语句
- 人工智障学习笔记——梯度下降(1)基础变种
- flutter 弹框 dialog,flutter提示框
- 【kafka】Kafka 幂等 Producer
- 【ambari】Ambari Rest api 使用
- 性能测试中容易混淆的概念
- 【Silverlight】Bing Maps学习系列(八):使用Bing Maps Silverlight Control加载自己部署的Google Maps...
- 用CSS绘制实体三角形并说明原理
- activemq 搭建2
- 手机号段归属地数据库
- RHEL7设置默认启动图形化界面
- 根据经纬度查找附近的人计算公式
- 百度地图/腾讯地图/世界开源地图经纬度API查询接口
- 利用python下载fnl数据方法
- [PPPOE]PPPD源码分析