HNOI2018省队集训 Day3

时间:2020-05-28
本文章向大家介绍HNOI2018省队集训 Day3,主要包括HNOI2018省队集训 Day3使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

HNOI2018省队集训 Day3

circular

简单题

直接破环为链+倍增即可。

admirable

最开始想的是点分治,因为往上的路径有点不好搞,觉得题解肯定还有复杂度更小的做法就去看题解

然后发现可以处理出以某个儿子为根的f值,就可以直接dfs了,复杂度从\(nlog^3\)变成\(n(log^2+\sqrt n)\)。具体方法就是模拟一下多项式除以二项式再乘上一个二项式,同一size的儿子一起处理。

然后开始写,写了一半要预处理NTT单位根

#include<bits/stdc++.h>
using namespace std;
int read(){
	int x=0,pos=1;char ch=getchar();
	for(;!isdigit(ch);ch=getchar()) if(ch=='-') pos=0;
	for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
	return pos?x:-x;
} 
#define ll long long
#define FOR(i,a,b) for(register int i=(a);i<=(b);++i)
#define ROF(i,a,b) for(register int i=(a);i>=(b);--i)
typedef vector<int> poly
int n;
const int N = 200001;
const int mod = 998244353;
struct node{
	int v,nex;
}edge[N*2];
int head[N],top=0,sz[N],fa[N],deg[N];
poly sv[N],pw[N];
void add(int u,int v){
	edge[++top].v=v;
	edge[++top].nex=head[u];
	head[u]=top;
}
void dft()
poly operator *(const poly &a,const poly &b){
	poly A=a,B=b;
	int len=1;
	while(len<A.size()+B.size()) len*=2;
	init(len);
	poly C(len,0);
	dft(A,len,1);dft(B,len,1);
	FOR(i,0,len-1) C[i]=1ll*A[i]*B[i]%mod;
	
}
poly work(int l,int r){
	if(l==r) return {1,sv[now][l]};
	int mid=(l+r)>>1;
	return work(l,mid)*work(r,mid);
}
void dfs1(int now,int pre){
	sz[now]=1;fa[now]=pre;
	for(int i=head[now];i;i=edge[i].nex){
		int v=edge[i].v;
		if(v==pre) continue;
		dfs1(v,now);
		sz[now]+=sz[v]; 
		deg[now]++;
		sv[now].push_back(sz[v]);
	}
	pw[now]=work(0,deg[now]-1);
}
int main(){
	n=read();
	FOR(i,1,n-1){
		int u=read(),v=read();
		add(u,v);add(v,u);
	}
	dfs1(1,0);
	dfs2(1);
}

然后一看题目,模数1e9+9,噔 噔 咚(心肺停止)

写nm

考场上要么写n^2+链要么留到最后再淦吧

illustrious

打表神题

首先打表得出 \(f(i)\) 是i的出现次数,那么我们算1e6个数就可以得出3e9的f

然后 \(f(n)\) 的前缀和 \(g(n)\) 表示 \(f(m) = n\) 的最大的 m

那么 \(f(f(n))\) 表示序列中下标为 \(n\) 处的数(\(f(n)\) ) 的出现次数

\(g(f(n))\) 表示序列中最大的是 \(f(n)\) 的位置。

那么 \(g(f(n)) − f(f(n))\) 则表示序列中第一个等于 \(f(n)\) 的位置的前一个位置,即最后一个为 \(f(n) − 1\) 的位置,即 \(g(f(n) − 1)\)

然后考虑算 \(g(g(n))\)

\[\begin{aligned} g(g(n))-g(g(n-1)) &=\sum_{i=g(n-1)+1}^{g(n)} f(i) \\ &=\sum_{i=g(n-1)+1}^{g(n)} n \\ &=n \cdot f(n) \end{aligned} \]

所以 \(g(g(n))=\sum_{i=1}^{n} i \cdot f(i)\)
然后分段算一下

原文地址:https://www.cnblogs.com/lcyfrog/p/12979742.html