NOIp模拟赛 西行妖下
题目描述:
给出一棵n个节点的树,每个点初始m值为1。
你有三种操作:
1.Add l r k ,将l到r路径上所有点m值加k。
2.Multi l r k ,将l到r路径上所有点m值乘k。
3.Query l r ,设x是l到r路径上的点,y是x的m值。假设有1~y共y个点,随机打乱,求形成错排的概率。
(k<=1000,n<=80000)
题解:
树剖正解?
(反正我用的dfs序+并查集)
首先1000^80000错排怎么搞啊?
要明白我们真正要的并不是错排数,而是错排数/阶乘。
打表后发现他是:
0.0,0.5,0.333333333,0.375,0.366666667,0.368055556,0.367857143,0.367881944,0.367879464
最后一位用的一般值。
(后来发现这个精度依然不够,要用错排递推直接打表。不然会卡精。)
树链怎么修改啊?
其实可以用单点修改……
重点在于一共只有80000个点,如果m值超过15就不用处理了,保留15位就够了……
所以单点最多修改80000*15次……
并查集维护。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
//lgl AK in NOIp
#define N 80050
double num[],tmp[];
void init()
{
double now = ;
tmp[]=0.0,tmp[]=1.0;
num[]=0.5;
for(int i=;i<;i++)
{
now*=(double)i;
tmp[i]=(double)(i-)*(tmp[i-]+tmp[i-]);
num[i]=(double)tmp[i]/now;
}
}
int n,hed[N],cnt,q;
char ch[];
struct EG
{
int to,nxt;
}e[*N];
void ae(int ff,int t)
{
e[++cnt].to = t;
e[cnt].nxt = hed[ff];
hed[ff] = cnt;
}
struct aaafku
{
int s[*N];
void ins(int x,int d)
{
while(x<*N)
{
s[x]+=d;
x+=(x&(-x));
}
}
int qry(int x)
{
int ret = ;
while(x)
{
ret+=s[x];
x-=(x&(-x));
}
return ret;
}
}f[];
int las[N];
int dep[N],siz[N],fa[N],son[N],top[N],typ[N];
int tin[N],tout[N],tim;
void dfs1(int u,int ff)
{
tin[u]=++tim;
typ[u]=;
siz[u]=;
dep[u]=dep[ff]+;
las[u]=u;
f[].ins(tin[u],);
for(int j=hed[u];j;j=e[j].nxt)
{
int to = e[j].to;
if(to==ff)continue;
fa[to]=u;
dfs1(to,u);
siz[u]+=siz[to];
if(siz[to]>siz[son[u]])son[u]=to;
}
tout[u]=tim;
f[].ins(tout[u]+,-);
}
void dfs2(int u,int tp)
{
top[u] = tp;
if(!son[u])return ;
dfs2(son[u],tp);
for(int j=hed[u];j;j=e[j].nxt)
{
int to = e[j].to;
if(to!=fa[u]&&to!=son[u])
dfs2(to,to);
}
}
int get_lca(int x,int y)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])swap(x,y);
x=fa[top[x]];
}
return dep[x]<dep[y]?x:y;
}
int get_las(int x)
{
if(las[x]==x)return x;
return las[x]=get_las(las[x]);
}
void deala(int u,int k,int lim)
{
if(dep[u]<=lim)return ;
f[typ[u]].ins(tin[u],-);
f[typ[u]].ins(tout[u]+,);
typ[u] = min(,typ[u]+k);
f[typ[u]].ins(tin[u],);
f[typ[u]].ins(tout[u]+,-);
deala(get_las(fa[u]),k,lim);
if(typ[u]==)las[u]=fa[u];
}
void dealb(int u,int k,int lim)
{
if(dep[u]<=lim)return ;
f[typ[u]].ins(tin[u],-);
f[typ[u]].ins(tout[u]+,);
typ[u] = min(,typ[u]*k);
f[typ[u]].ins(tin[u],);
f[typ[u]].ins(tout[u]+,-);
dealb(get_las(fa[u]),k,lim);
if(typ[u]==)las[u]=fa[u];
}
int main()
{
// freopen("yuyuko.in","r",stdin);
// freopen("yuyuko.out","w",stdout);
init();
scanf("%d",&n);
for(int ff,t,i=;i<n;i++)
{
scanf("%d%d",&ff,&t);
ae(ff,t),ae(t,ff);
}
dfs1(,),dfs2(,);
scanf("%d",&q);
for(int l,r,k,i=;i<=q;i++)
{
scanf("%s",ch+);
if(ch[]=='Q')
{
scanf("%d%d",&l,&r);
int lca = get_lca(l,r);
int ff = fa[lca];
double ans = 0.0;
for(int j=;j<;j++)
{
int sum = f[j].qry(tin[l])+f[j].qry(tin[r])-f[j].qry(tin[lca])-f[j].qry(tin[ff]);
ans+=(double)sum*num[j];
}
printf("%.1lf\n",ans);
}else
{
scanf("%d%d%d",&l,&r,&k);
int lca = get_lca(l,r);
if(ch[]=='A')
{
deala(las[l],k,dep[lca]);
deala(las[r],k,dep[lca]-);
}else
{
dealb(las[l],k,dep[lca]);
dealb(las[r],k,dep[lca]-);
}
}
}
return ;
}
NOIp模拟赛 西行妖下的更多相关文章
- NOIP模拟赛20161022
NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...
- NOIP模拟赛 by hzwer
2015年10月04日NOIP模拟赛 by hzwer (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...
- 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程
数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...
- 【noip模拟赛5】细菌 状压dp
[noip模拟赛5]细菌 描述 近期,农场出现了D(1<=D<=15)种细菌.John要从他的 N(1<=N<=1,000)头奶牛中尽可能多地选些产奶.但是如果选中的奶牛携 ...
- NOI.AC NOIP模拟赛 第六场 游记
NOI.AC NOIP模拟赛 第六场 游记 queen 题目大意: 在一个\(n\times n(n\le10^5)\)的棋盘上,放有\(m(m\le10^5)\)个皇后,其中每一个皇后都可以向上.下 ...
- NOI.AC NOIP模拟赛 第四场 补记
NOI.AC NOIP模拟赛 第四场 补记 子图 题目大意: 一张\(n(n\le5\times10^5)\)个点,\(m(m\le5\times10^5)\)条边的无向图.删去第\(i\)条边需要\ ...
- NOI.AC NOIP模拟赛 第三场 补记
NOI.AC NOIP模拟赛 第三场 补记 列队 题目大意: 给定一个\(n\times m(n,m\le1000)\)的矩阵,每个格子上有一个数\(w_{i,j}\).保证\(w_{i,j}\)互不 ...
- 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护
线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...
- 2016-06-19 NOIP模拟赛
2016-06-19 NOIP模拟赛 by coolyangzc 共3道题目,时间3小时 题目名 高级打字机 不等数列 经营与开发 源文件 type.cpp/c/pas num.cpp/c ...
随机推荐
- Asp.net Mvc 数据库上下文初始化器
在Asp.net Mvc 和Entity FrameWork程序中,如果数据库不存在,EF默认的行为是新建一个数据库.如果模型类与已有的数据库不匹配的时候,会抛出一个异常. 通过指定数据库上下文对象初 ...
- CodeForces 721B Passwords (水题)
题意:给定 n 个密码,你要按长度不递减的顺序进行尝试,问你最多和最少试多少次可能找出密码,每尝试 k 次错误的,就要等5秒. 析:我们只要把长度全都统计下来,然后从1开始去找目标长度,最少的就是正好 ...
- bzoj 4815: [Cqoi2017]小Q的表格【欧拉函数+分块】
参考:http://blog.csdn.net/qq_33229466/article/details/70174227 看这个等式的形式就像高精gcd嘛-所以随便算一下就发现每次修改(a,b)影响到 ...
- 洛谷 P4011 孤岛营救问题【bfs】
注意: 一个点可能有多把钥匙,所以把每个点有钥匙的情况状压一下 两个点之间有障碍的情况只给出了单向,存的时候记得存一下反向 b[i][j]表示当前点拥有钥匙的状态,g[x1][y1][x2][y2]表 ...
- Luogu P1134 阶乘问题 【数学/乱搞】 By cellur925
输入输出格式 输入格式: 仅一行包含一个正整数 NN . 输出格式: 一个整数,表示最右边的非零位的值. 输入输出样例 输入样例#1: 12 输出样例#1: 6 说明 USACO Training S ...
- [ZOJ1610]Count the Colors
Description 画一些颜色段在一行上,一些较早的颜色就会被后来的颜色覆盖了. 你的任务就是要数出你随后能看到的不同颜色的段的数目. Input 每组测试数据第一行只有一个整数n, 1 < ...
- Windows软件推荐
本篇博文主要记录一些实用性的windows软件或者插件,重在积累! 工具类 1.截图软件 https://zh.snipaste.com/ Snipaste 是一个简单但强大的截图工具,也可以让你将截 ...
- python面向对象的3个特点
封装 封装是从业务逻辑中抽象对象时,要赋予对象相关数据与操作,将一些数据和操作打包在一起的过程.封装是使用对象的主要魅力之一,它提供了一个简单方法来创建复杂方案,解决了世界是如何工作的这一问题,我们自 ...
- IOS编译报错:objc-class-ref in AppDelegate.o之解决方案 Xcode7
Undefined symbols for architecture x86_64: "_OBJC_CLASS_$_QQApiInterface", referenced from ...
- 转】在Ubuntu中安装Redis
不多说,直接上干货! 原博文出自于: http://blog.fens.me/category/%E6%95%B0%E6%8D%AE%E5%BA%93/ 感谢! 在Ubuntu中安装Redis R利剑 ...