[グループ] [NOIP2019 JZOJ Aシミュレーション2019年9月11日] Treap(Treap)

タイトル

【課題】説明
小Dは、n個のノードのツリーを有し、1〜nは、各ノードの数を得ました。コンパイルされたすべてのノードの
数は、互いに異なっています。
最近、小さなD非常に興味を持ってヒープのためには、ので、彼はこのツリーノードの研究炉の自然を期待しています。小さなDのためには
比較的小さいので、彼の研究は、小さな根ヒープです。
まず、小Dは、ツリーのルートノードとして選択されます。次に、ツリーの各ノードについて、それがプログラムされたかどう
番号は、ノードDがヒープ性を満たすと言われるほど小さく、その最小をルートとするサブツリーです。
少数のDの前に割り当て、よりカジュアルなので、そうヒープ性を満たしていないノードが存在してもよいです。
この時点で、スタックはツリー全体重みはPKであることをD小さいような、kのツリーノードの性質を満たすように提供され
、pが小さい予め設定された定数Dです。
今、中等度の確率n個のプログラムの!ランダム種類番号方式から小さなDと仮定し、その後、プログラムのn個の種類の中から
、ツリーの期待値が右の数である、ランダムにルートプログラム確率の一種を選択?
XYの端数(?GCD(、)= 1でなければならないことが望まなるかもしれない ?)、 あなたはこのスコアのうちせればあなたは死ぬの
?X-⋅Y-MOD-1 X-998 244 353 =⋅:結果の998 244 353
998 244 351 998 244 353 MODを。
[入力形式は
treap.inで、入力ファイルから読み取ります。
二つの整数N、P、それぞれ、Dが配置されたツリー定数の小さいサイズの最初の行。
次に、N -二つの整数の1行は、ツリーの一面を表します。
[出力形式]
で、ファイルtreap.outに出力。
答を表し出力ラインアン整数。
入力[1]サンプル
18は1
1 2
1 3
1 4
1 16
2.5
。3.6
。4. 7
の2019年非専門家レベルのソフトウェア認証機能が増加ステージ(第2ラウンド)は、第2の認証Treap(Treap)ページ8 8
。4〜12である
。4. 17
。5。8
。6。9
。6 11
。6〜13である
。7 10
7 14
15 9
15 18である
[出力1]試料
1
[サンプル1]解釈
ツリーの任意の、以降PK = 1K = 1、そう重み1は、自然の重みが1であると予想されています。
サンプル入力[2]
。3 2
1 2
。1. 3
[出力]サンプル2
776 412 279
[サンプル2]説明
21の重量と、全てのプログラムの4つ、22の重量、23の重量を有する10種を有します4があります。
総重量が80であるので、所望の重み値は80であり、
18は

40
下型センス9 776 412 279。
サンプル[3]
treap / treap3.inとtreap / treap3.ans次のプレイヤーのディレクトリを参照してください。
[サブ]タスク
のテストポイントの10%を、そのN≤10を確保します。
テストポイントの20%をそのN≤18を確保します。
テストポイントの30%をそのN≤100を確保します。
テストポイントの50%は、n≤1000確実にします。
そのP≤1を確保するためのテストポイントの他の10%。
ツリーがチェーンであることを確認するためのテストポイントの他の10%。
テストポイントの他の10%、その他の点に接続されているツリーポイントの存在を確保します。
テストポイントの100%に1≤N≤106、0≤ことを確実にするために 、P <998244353を。

思考

固定根の場合を考えてみましょう。[CTS2019]クリプトン金の手の旅行体験することで、あなたが得ることができる:各点は、ヒープを満たすために、イベントの性質である、彼らは互いに独立しています。そして、確率は、そのサブ根付いた木の逆数に等しいです。
従ってDPを行うことができる。πchild(X)(SIZE( X)+ P-1)/サイズ(X)。

ケース変数の根、およびすべてのルートの計算所望の平均値に対応するため。私たちは、単純にすべての可能なルートを列挙してDPあり、そして最後に平均しました。

しかし、あまりにも遅いです

方程式の形に着目し、ルート変更は、これだけ再びDPを変更することができDFSルートを達成し、DPのために簡単です。

しかし、唯一の70のポイント

(SIZE(X)+ P-これは、 1)/サイズ(X)は、センスダイに等しくてもよいです。
我々は、このような神の馬のプレフィックスとサフィックス製品として柯技術のいくつかを実装する必要がありますので。
しかし、あまりにも多くの問題があるように必要はありません。すべての式の積ので、ゼロ係数の数(すなわち、標準式分解指数MOD)と、それの残りの部分の値を維持することのみが必要です。

コード

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e6+77,mod=998244353;
int ls[N],s[N],n,cnt,q[N],nq;
ll h[N],f[N],g[N],p,invs[N],pre[N];
struct E
{
	int to,next;
}e[N*2];
void add(int u,int v)
{
	e[++cnt].to=v; e[cnt].next=ls[u]; ls[u]=cnt;
}
inline ll ny(ll x)
{
	ll ass=1;
	for(int y=mod-2; y; y>>=1,x=x*x%mod) if(y&1) ass=ass*x%mod;
	return ass;
}
inline ll calc(int s)
{
	return (p*invs[s]+1-invs[s]+mod)%mod;
}
void dfs1(int u,int fa)
{
	s[u]=1,h[u]=1;
	for(int i=ls[u]; i; i=e[i].next)
		if(e[i].to!=fa)
		{
			int v=e[i].to;
			dfs1(v,u);
			s[u]+=s[v];
			h[u]=h[u]*f[v]%mod;
		}
	f[u]=h[u]*calc(s[u])%mod;
}
ll ans;
void dfs2(int u,int fa)
{
	ans=(ans+h[u]*g[u]%mod*calc(n))%mod;
	pre[q[nq=0]=0]=1;
	for(int i=ls[u]; i; i=e[i].next)
		if(e[i].to!=fa)
		{
			int v=e[i].to;
			pre[v]=pre[q[nq]]*f[v]%mod;
			q[++nq]=v;
		}
	ll suc=1;
	for(int i=nq; i>=1; i--)
	{
		g[q[i]]=pre[q[i-1]]*suc%mod*g[u]%mod*calc(n-s[q[i]])%mod;
		suc=suc*f[q[i]]%mod;
	}
	for(int i=ls[u]; i; i=e[i].next)
		if(e[i].to!=fa)
		{
			int v=e[i].to;
			dfs2(v,u);
		}
}
int main()
{
	freopen("treap.in","r",stdin); freopen("treap.out","w",stdout);
	scanf("%d%d",&n,&p);
	invs[1]=1;
	for(int i=2; i<=n; i++) invs[i]=(mod-mod/i)*invs[mod%i]%mod;
	for(int i=1,x,y; i<n; i++)
	{
		scanf("%d%d",&x,&y); add(x,y); add(y,x);
	}
	dfs1(1,0);
	g[1]=1; dfs2(1,0);
	ans=ans*ny(n)%mod;
	printf("%lld",ans);
}
703元記事公開 ウォンの賞賛392 ビューに14万+を

おすすめ

転載: blog.csdn.net/Eric1561759334/article/details/100786259
おすすめ