51 nod 1628 非波那契树
原题链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1628
花了一个早上+半个下午终于把这题切掉了……
(膜出题人)
我们考虑斐波那契数列的通项公式:
$$ F(i)=[(\frac{1+\sqrt{5}}{2})^{i}-(\frac{1-\sqrt{5}}{2})^{i}]*\frac{1}{\sqrt{5}} $$
最后的$ \frac{1}{\sqrt{5}} $ 我们可以拿掉,输出时再丢进答案。
然后考虑对前面两项分开单独处理。
设$G(i)=(\frac{1+\sqrt{5}}{2})^{i}$ 那么这时可以发现 $G(a+b)=G(a)*G(b)$ 有了这个性质,我们就可以把东西统计完再乘起来了。
具体来说,先预处理出从一个点向上走$2^{i}$步之后,这条链上的点从下往上走能得到的贡献,从上往下相同,以及该链内部的点两两之间对答案的贡献(其实前面从上往下的统计只是为这部分服务)。
对于每组询问,先求出两点的lca,然后分别统计这两个点到lca的链的答案,再合并起来,合并的过程有很多细节,详见代码。
运气#1(UPD at 2017.4.24:已经被踩辣)
#include<cstdio>
#include<algorithm>
#define MN 100001
using namespace std;
int read_p,read_ca;
inline int read(){
read_p=;read_ca=getchar();
while(read_ca<''||read_ca>'') read_ca=getchar();
while(read_ca>=''&&read_ca<='') read_p=read_p*+read_ca-,read_ca=getchar();
return read_p;
}
const int S1=,S2=,MOD=1e9+,S3=;
struct na{int y,ne;}b[MN<<];
int n,m,x,y,f[MN][],g[MN][],G[MN][],A[MN][],K[MN][],l[MN],num=,S[][MN],X[MN],Y[MN],Z[MN],s[MN],de[MN],mmh[MN],Lx[MN],Ly[MN],AP[MN];
inline void in(int x,int y){b[++num].y=y;b[num].ne=l[x];l[x]=num;}
inline int M(int x){while (x>=MOD)x-=MOD;while (x<)x+=MOD;return x;}
void DFS(int x){
s[x]=;
register int i;
for (i=;i<=;i++) if (f[f[x][i-]][i-]) f[x][i]=f[f[x][i-]][i-];else break;
for (i=;i<=;i++) if (f[K[x][i-]][i]) K[x][i]=f[K[x][i-]][i];else break;
for (;i;i--) K[x][i]=K[x][i-];K[x][]=x;
for (i=l[x];i;i=b[i].ne)
if (b[i].y!=f[x][]){
de[b[i].y]=de[K[b[i].y][]=f[b[i].y][]=x]+;
DFS(b[i].y);
AP[x]=M(AP[x]+1LL*s[x]*s[b[i].y]%MOD);
s[x]+=s[b[i].y];
}
}
inline int lca(int x,int y,int &a,int &b){
for (register int i=;i>=;i--)
if (de[f[x][i]]>=de[y]) x=f[x][i];
if (x==y) return x;
for (register int i=;i>=;i--)
if (f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
a=x;b=y;
return f[x][];
}
void dfs(int x,int o){
A[x][]=1LL*AP[x]*S[o][]%MOD;
g[x][]=G[x][]=1LL*s[x]*S[o][]%MOD;
for (register int i=;i<=;i++)
if (K[x][i])
g[x][i]=M((1LL*(g[x][i-]-s[K[x][i-]])*S[o][<<(i-)]+g[f[x][i-]][i-])%MOD),
G[x][i]=M((1LL*(G[f[x][i-]][i-]-g[K[x][i-]][])*S[o][<<(i-)]+G[x][i-])%MOD),
A[x][i]=M((1LL*g[x][i-]*(G[f[x][i-]][i-]-g[K[x][i-]][])+A[x][i-]+A[f[x][i-]][i-]-1LL*s[K[x][i-]]*M(G[f[x][i-]][i-]-g[K[x][i-]][]))%MOD);
for (register int i=l[x];i;i=b[i].ne)
if (b[i].y!=f[x][]) dfs(b[i].y,o);
}
inline void work(int x,int z,int &_A,int &_g,int o){
int p=;_A=;_g=;
for (register int i=;i>=;i--)
if (de[K[x][i]]>=de[z]){
_A=M((1LL*_g*(G[x][i]-g[p][])+_A+A[x][i]-1LL*s[p]*M(G[x][i]-g[p][]))%MOD);
_g=M((1LL*(_g-s[p])*S[o][<<i]+g[x][i])%MOD);
if (K[x][i]==z) return;
p=K[x][i];
x=f[x][i];
}
}
inline void calc(int x){
int Ax,Ay,gx,gy;
register int i;
dfs(,x);
for (i=;i<=m;i++)
if (Y[i]==Z[i]){
work(X[i],Z[i],Ax,gx,x);
mmh[i]=M(mmh[i]+(x?-1LL:1LL)*(1LL*gx*(n-s[Z[i]])+Ax)%MOD);
}else{
work(X[i],Lx[i],Ax,gx,x);work(Y[i],Ly[i],Ay,gy,x);
mmh[i]=M(mmh[i]+(x?-1LL:1LL)*(1LL*(gx+gy)*(n-s[Lx[i]]-s[Ly[i]])%MOD*S[x][]+1LL*gx*gy%MOD*S[x][]+Ax+Ay+A[Z[i]][]-(1LL*s[Lx[i]]*(s[Z[i]]-s[Lx[i]])+1LL*s[Ly[i]]*(s[Z[i]]-s[Lx[i]]-s[Ly[i]]))%MOD*S[x][]+(1LL*(s[Z[i]]-s[Lx[i]]-s[Ly[i]])*(n-s[Z[i]]))%MOD*S[x][])%MOD);
}
}
int main(){
register int i;
n=read();
for (i=;i<n;i++) x=read(),y=read(),in(x,y),in(y,x);
S[][]=S[][]=;
for (i=;i<=n;i++) S[][i]=1LL*S[][i-]*S1%MOD,S[][i]=1LL*S[][i-]*S2%MOD;
de[]=;DFS();
m=read();
for (i=;i<=m;i++){
X[i]=read();Y[i]=read();
if (de[X[i]]<de[Y[i]]) swap(X[i],Y[i]);
Z[i]=lca(X[i],Y[i],Lx[i],Ly[i]);
}
calc();calc();
for (i=;i<=m;i++) printf("%d\n",1LL*mmh[i]*S3%MOD);
}
51 nod 1628 非波那契树的更多相关文章
- 51 Nod 1242 斐波那契数列的第N项(矩阵快速幂模板题)
1242 斐波那契数列的第N项 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 斐波那契数列的定义如下: F(0) = 0 F(1) = 1 F(n) ...
- 51 nod 1350 斐波那契表示
每一个正整数都可以表示为若干个斐波那契数的和,一个整数可能存在多种不同的表示方法,例如:14 = 13 + 1 = 8 + 5 + 1,其中13 + 1是最短的表示(只用了2个斐波那契数).定义F(n ...
- 51 nod 1427 文明 (并查集 + 树的直径)
1427 文明 题目来源: CodeForces 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 安德鲁在玩一个叫“文明”的游戏.大妈正在帮助他. 这个游 ...
- 如何在ABAP里用函数式编程思想打印出非波拉契Fibonacci(数列)
在JavaScript里可以用ES6提供的FunctionGenerator这种黑科技来打印非波拉契数列,具体细节参考我这篇文章. 在ABAP里也有很多种方式实现这个需求. 下面这个report分别用 ...
- 使用JavaScript ES6的新特性计算Fibonacci(非波拉契数列)
程序员面试系列 Java面试系列-webapp文件夹和WebContent文件夹的区别? 程序员面试系列:Spring MVC能响应HTTP请求的原因? Java程序员面试系列-什么是Java Mar ...
- Codeforces 719E [斐波那契区间操作][矩阵快速幂][线段树区间更新]
/* 题意:给定一个长度为n的序列a. 两种操作: 1.给定区间l r 加上某个数x. 2.查询区间l r sigma(fib(ai)) fib代表斐波那契数列. 思路: 1.矩阵操作,由矩阵快速幂求 ...
- Codeforces 446-C DZY Loves Fibonacci Numbers 同余 线段树 斐波那契数列
C. DZY Loves Fibonacci Numbers time limit per test 4 seconds memory limit per test 256 megabytes inp ...
- 51 nod 1681 公共祖先 (主席树+dfs序)
1681 公共祖先 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 有一个庞大的家族,共n人.已知这n个人的祖辈关系正好形成树形结构(即父亲向儿子连边). 在另 ...
- 51 nod 1766 树上的最远点对(线段树+lca)
1766 树上的最远点对 基准时间限制:3 秒 空间限制:524288 KB 分值: 80 难度:5级算法题 n个点被n-1条边连接成了一颗树,给出a~b和c~d两个区间,表示点的标号请你求出两个 ...
随机推荐
- 一个两年java程序猿的2017个人总结
前言 又到了一年中最后的日子了,相信有不少公司要求员工写年度总结了,我也不例外.不过个人感觉在公司的写个年度总结来说,过于模板化了.其实很多没有必要.总之,本篇的个人总结,是按照个人的想法写的.简而言 ...
- ArcGIS API for JavaScript 4.2学习笔记[31] (补充学习)Task类
Task这个东西很有用,是AJS中用于解决各种乱七八糟任务的一个类.它有很多子类,有用于空间分析的,有用于空间查询的,等等. 这篇作为补充学习的第一篇,也是进阶学习的第一篇,我就改个写法. 我将使用思 ...
- bzoj 4538: [Hnoi2016]网络
Description 一个简单的网络系统可以被描述成一棵无根树.每个节点为一个服务器.连接服务器与服务器的数据线则看做一条树边.两个服务器进行数据的交互时,数据会经过连接这两个服务器的路径上的所有服 ...
- 阿里云ECS升级OpenSSL记录
1.下载OpenSSL wget https://www.openssl.org/source/openssl-1.1.0e.tar.gz 2.解压编译安装 tar xf openssl-1.1.0e ...
- tcpdump 命令详解
TCPdump: dump traffic on a network ,根据使用者的定义对网络上的数据包进行截获的一种包分析工具. TCPdump 可以讲网络中传送的数据包的 头信息完全截获下来提供 ...
- Talk 3: Rob Pike on Upspin (Gopherfest 2017)
Talk 3: Rob Pike on Upspin Upspin is an experimental project to build a framework for naming and sha ...
- [编织消息框架][JAVA核心技术]动态代理应用6-设计生成类
上篇介绍到rpc可以使用接口与实现类来约束书写 根据接口用javassist生成两个代理类 1.sendProxy 发送处理,调用方式可以是远程/本地 2.receiveProxy 接收处理,内部调用 ...
- PHP进阶,使用交互模式进行快速测试实验?
额,那啥,PHP很强,大家都知道哈.不过呢,在搞PHP里的人中,自然也要分高下的.当然了,我更喜欢用好玩来形容了. 什么叫做快速开发?我觉得,快就得快到随手写几个字,就能让代码跑起来!那么,PHP能做 ...
- Head First设计模式之中介者模式
一.定义 又称为调停者模式,定义一个中介对象来封装系列对象之间的交互.中介者使各个对象不需要显示地相互引用,从而使其耦合性松散,而且可以独立地改变他们之间的交互. 二.结构 组成: ● 抽象中介者(M ...
- Class StatusesTableSeeder does not exist 如何解决
Class StatusesTableSeeder does not exist错误如何解决 Laravel 5.* 执行seeder命令出现错误的解决方法 最近在使用Laravel开发一个项 ...