5.15 省选模拟赛 T1 点分治 FFT
LINK:5.15 T1


对于60分的暴力 都很水 就不一一赘述了.
由于是询问所有点的这种信息 确实不太会.
想了一下 如果只是询问子树内的话 dsu on tree还是可以做的。
可以自己思考一下.
如果强行dsu的时候做 会发现点对和点对之间难以解决。
考虑正解 点分治:
当x为分治中心还是需要统计点对和点对之间的贡献.
和刚才几乎一样.不过这个时候可以发现 需要对每个点都求一个答案.
对于深度为w的点 那么 贡献为\(\sum_{j=w}^{n}c_{j-w}a_j\)
其中\(c_x\)表示当前深度为x的点的个数 不过这个可能统计到自己的那条链中的答案.
不过可以再对每个子树内做一遍 减掉即可。
那么我们发现这样做的话 每一个深度的点 答案其实是一样的.
这样对于上面的东西 其实可以看成是一个卷积.
这个卷积比较奇特 是相减的形式 可以变形 两边同时加上n-1就变成了正常的卷积。
对于重复的 可以发现可以被减掉 所以这样做事正确的。
值域原因 不能使用NTT 所以上FFT 常数太大可以选择预处理单位根.
const int MAXN=600010;
const db Pi=acos(-1.0);
int n,root,lim,len;
int w[MAXN],sz[MAXN],son[MAXN],c[MAXN],ans[MAXN],vis[MAXN];
int lin[MAXN],ver[MAXN],nex[MAXN],rev[MAXN],v[MAXN],d[MAXN];
struct wy
{
db r,v;
wy(db x=0,db y=0){r=x;v=y;}
wy friend operator *(wy a,wy b){return wy(a.r*b.r-a.v*b.v,a.r*b.v+b.r*a.v);}
wy friend operator +(wy a,wy b){return wy(a.r+b.r,a.v+b.v);}
wy friend operator -(wy a,wy b){return wy(a.r-b.r,a.v-b.v);}
}A[MAXN],B[MAXN],w0[20][MAXN],w1[20][MAXN];
inline void add(int x,int y)
{
ver[++len]=y;nex[len]=lin[x];lin[x]=len;
ver[++len]=x;nex[len]=lin[y];lin[y]=len;
}
inline void get_root(int x,int fa,int n)
{
sz[x]=1,son[x]=0;
go(x)if(tn!=fa&&!vis[tn])
{
get_root(tn,x,n);
sz[x]+=sz[tn];
son[x]=max(son[x],sz[tn]);
}
son[x]=max(son[x],n-sz[x]);
if(son[x]<son[root])root=x;
}
inline void get_dis(int x,int fa,int dep)
{
d[x]=dep;++c[d[x]];
go(x)if(tn!=fa&&!vis[tn])get_dis(tn,x,dep+1);
}
inline void FFT(wy *a,int op)
{
rep(0,lim-1,i)if(i<rev[i])swap(a[i],a[rev[i]]);
for(int len=2,cc=0;len<=lim;len=len<<1,++cc)
{
int mid=len>>1;
for(int j=0;j<lim;j+=len)
{
for(int i=0;i<mid;++i)
{
wy x=a[i+j],y=a[i+j+mid]*(op==-1?w1[cc][i]:w0[cc][i]);
a[i+j]=x+y;a[i+j+mid]=x-y;
}
}
}
if(op==-1)rep(0,lim-1,i)a[i].r=a[i].r/lim;
}
inline void js(int n)
{
reverse(c,c+n);
int sz1=n,sz2=n+n-1;
lim=1;
while(lim<sz1+sz2-1)lim=lim<<1;
rep(0,lim-1,i)rev[i]=rev[i>>1]>>1|((i&1)?lim>>1:0);
rep(0,sz1-1,i)A[i]=wy(c[i],0);rep(sz1,lim-1,i)A[i]=wy(0,0);
rep(0,sz2-1,i)B[i]=wy(w[i],0);rep(sz2,lim-1,i)B[i]=wy(0,0);
FFT(A,1);FFT(B,1);
rep(0,lim-1,i)A[i]=A[i]*B[i];
FFT(A,-1);
rep(0,n-1,i)v[i]=(int)(A[i+n-1].r+0.5);
}
inline void get_ans(int x,int fa,int op)
{
if(op)ans[x]+=v[d[x]];
else ans[x]-=v[d[x]];
go(x)if(tn!=fa&&!vis[tn])
get_ans(tn,x,op);
}
inline void solve(int x,int n,int op)
{
if(op)
{
rep(0,n,i)c[i]=0;
get_dis(x,0,1);
js(n+1);
get_ans(x,0,0);
}
//if(dep>30){cout<<"ww"<<endl;exit(0);}
root=0;get_root(x,0,n);
//cout<<root<<' '<<son[root]<<' '<<sz[root]<<endl;
rep(0,n,i)c[i]=0;
get_dis(root,0,0);
vis[root]=1;js(n);
get_ans(root,0,1);
int ww=root;
go(ww)
if(!vis[tn])
{
//cout<<(sz[tn]>sz[ww]?n-sz[ww]:sz[tn])<<endl;
solve(tn,sz[tn]>sz[ww]?n-sz[ww]:sz[tn],1);
}
}
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
get(n);
rep(0,n-1,i)get(w[i]);
rep(2,n,i)add(read(),read());
for(int i=2,j=0;j<20;i=i<<1,++j)
{
int mid=i>>1;
wy wn=wy(cos(Pi/mid),sin(Pi/mid));
wy d=wy(1,0);
for(int k=0;k<mid;++k)
{
w0[j][k]=d;w1[j][k]=d;
w1[j][k].v=-w1[j][k].v;
d=d*wn;
}
}
son[0]=n+1;solve(1,n,0);
rep(1,n,i)put_(ans[i]);
return 0;
}
5.15 省选模拟赛 T1 点分治 FFT的更多相关文章
- 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解
今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...
- 6.15 省选模拟赛 老魔杖 博弈论 SG函数
这道题确实没有一个很好的解决办法 唯一的正解可能就是打表找规律 或者 直接猜结论了吧. 尽管如此 在此也给最终结论一个完整的证明. 对于70分 容易发现状态数量不大 可以进行暴力dp求SG函数. 原本 ...
- 5.15 省选模拟赛 容斥 生成函数 dp
LINK:5.15 T2 个人感觉生成函数更无脑 容斥也好推的样子. 容易想到每次放数和数字的集合无关 所以得到一个dp f[i][j]表示前i个数字 逆序对为j的方案数. 容易得到转移 使用前缀和优 ...
- NOI 2019 省选模拟赛 T1【JZOJ6082】 染色问题(color) (多项式,数论优化)
题面 一根长为 n 的无色纸条,每个位置依次编号为 1,2,3,-,n ,m 次操作,第 i 次操作把纸条的一段区间 [l,r] (l <= r , l,r ∈ {1,2,3,-,n})涂成颜色 ...
- 洛谷[LnOI2019]长脖子鹿省选模拟赛t1 -> 快速多项式变换
快速多项式 做法:刚拿到此题有点蒙,一开始真没想出来怎么做,于是试着去自己写几个例子. 自己枚举几种情况之后就基本看出来了,其实本题中 n 就是f(m)在m进制下的位数,每项的系数就是f(m)在m进制 ...
- 5.20 省选模拟赛 T1 图 启发式合并 线段树合并 染色计数问题
LINK:图 在说这道题之前吐槽一下今天的日子 520 = 1+1+4+514. /cy 这道题今天做的非常失败 一点分都没拿到手 关键是今天的T3 把我整个人给搞崩了. 先考虑 如果得到了这么一张图 ...
- 5.19 省选模拟赛 T1 小B的棋盘 双指针 性质
LINK:小B的棋盘 考试的时候没有认真的思考 导致没做出来. 容易发现 当k>=n的时候存在无限解 其余都存在有限解 对于30分 容易想到暴力枚举 对称中心 然后 n^2判断. 对于前者 容易 ...
- 4.15 省选模拟赛 编码 trie树 前缀和优化建图 2-sat
好题 np. 对于20分 显然可以爆搜. 对于50分 可以发现每个字符串上的问号要么是0,要么是1.考虑枚举一个字符串当前是0还是1 这会和其他字符串产生矛盾. 所以容易 发现这是一个2-sat问题. ...
- 20180610模拟赛T1——脱离地牢
Description 在一个神秘的国度里,年轻的王子Paris与美丽的公主Helen在一起过着幸福的生活.他们都随身带有一块带磁性的阴阳魔法石,身居地狱的魔王Satan早就想着得到这两块石头了,只要 ...
随机推荐
- 创建新用户后无法切换 su: failed to execute /bin/bash: Permission denied
创建新用户后无法切换 su: failed to execute /bin/bash: Permission denied 当使用 su username 从root切换用户时显示 su: fai ...
- DP没入门就入土
写在前面 记录最近刷的DP题 以及 打死都不可能想到状态设计DP系列 汇总 洛谷 P6082 [JSOI2015]salesman 树形\(\texttt{DP}\) + 优先队列 比较容易看出来这是 ...
- P1330 封锁阳光大学——深度优先搜索DFS
P1330 封锁阳光大学 题目描述 曹是一只爱刷街的老曹,暑假期间,他每天都欢快地在阳光大学的校园里刷街.河蟹看到欢快的曹,感到不爽.河蟹决定封锁阳光大学,不让曹刷街. 阳光大学的校园是一张由 \(n ...
- 「JLOI2015」城池攻占 可并堆
传送门 分析 如果直接暴力枚举的话肯定会超时 我们可以从下往上遍历,维护一个小根堆 每次到达一个节点把战败的骑士扔出去 剩下的再继续向上合并,注意要维护一下其实的战斗力 可以像线段树那样用一个lazy ...
- Shein一面(视频面)07.07
应聘职位:Java工程师 时长:30min 面经: Spring讲一下 SpringAOP用到什么设计模式 JVM包括什么 运行时数据区包括什么 什么时候入栈,出栈 Sychronized和可重入锁区 ...
- MVC引用asp.net报表(测试小例子)
public class Default1Controller : Controller { // // GET: /Default1/ public ActionResult Index() { r ...
- pytest框架使用教程
Pytest框架 一.简介 pytest:基于unittest之上的单元测试框架 有什么特点? 自动发现测试模块和测试方法 断言更加方便,assert + 表达式,例如 assert 1 == 1 灵 ...
- 普通平衡树学习笔记之Splay算法
前言 今天不容易有一天的自由学习时间,当然要用来"学习".在此记录一下今天学到的最基础的平衡树. 定义 平衡树是二叉搜索树和堆合并构成的数据结构,它是一 棵空树或它的左右两个子树的 ...
- 数据可视化之powerBI基础(八)PowerBI的表格,你真的会用吗
https://zhuanlan.zhihu.com/p/64413000 在PowerBI的可视化对象中,还有两个「表格」对象,表格的作用不仅可以在报表提供明细数据,还经常用来测试度量值的返回结果, ...
- js自定义获取浏览器宽高
/** * @description js自定义获取浏览器宽高 * * IE8 和 IE8 以下的浏览器不兼容 * window.innerWidth * window.innerHeight * * ...