容斥,强制若干条链不重要,即有$2^{n-1-s}$种(其中$s$为这些链的并所覆盖的边数),暴力将选中的链打标记,时间复杂度$o(m^{2}2^{m}+n\log_{2}n)$(预处理出这$2m$个点的虚树),期望得分32(实际得分40)

考虑在计算$s$时可以差分来统计,时间复杂度可以做到$o(m2^{m}+n\log_{2}n)$,期望得分40

考虑另一种优化方法:按照dfs的顺序去枚举,每一次枚举$v=k$的所有链的状态,并维护当前子树内的被选择的深度最小的$u$(如果$u$在$k$子树中令$u=k$),这样的时间复杂度也是$o(m2^{m}+n\log_{2}n)$

观察到当处理完$k$子树后,影响答案的只有:1.深度最小的$u$(的深度);2.所覆盖的边数$s$(仅考虑子树内部),那么用$f[k][u][s]$表示对应的方案数(方案有“正负”),时间复杂度$o(n^{4})$

考虑优化,不妨令$dp[k][u]=\sum_{i=0}^{n-1}f[k][u][i]\cdot 2^{sz[k]-1-i}$,后者具有可乘性,因此可以转移(注意:转移过程中$sz[k]-1$的意义为考虑过的边数量),时间复杂度$o(n^{2})$

记$S[k][u]=\sum_{i=u}^{dep_{k}}dp[k][i]$,简单化简,可以发现新的转移式为$S[k][u]=\prod_{son}(S[son][u]+S[son][dep_{son}])$

考虑用线段树来维护这个dp数组,那么要支持:1.区间加;2.对应位置相乘

维护加法标记和乘法标记,然后线段树合并即可,时间复杂度$o(n\log_{2}n)$

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 500005
4 #define mod 998244353
5 #define mid (l+r>>1)
6 #define pii pair<int,int>
7 #define fi first
8 #define se second
9 struct ji{
10 int nex,to;
11 }edge[N<<1];
12 vector<int>v[N];
13 int V,E,n,m,x,y,head[N],s[N],r[N],ls[N*40],rs[N*40];
14 pii tag[N*40];
15 void add(int x,int y){
16 edge[E].nex=head[x];
17 edge[E].to=y;
18 head[x]=E++;
19 }
20 void upd(int k,pii x){
21 tag[k].fi=1LL*tag[k].fi*x.fi%mod;
22 tag[k].se=(1LL*tag[k].se*x.fi+x.se)%mod;
23 }
24 void down(int k){
25 if (ls[k])upd(ls[k],tag[k]);
26 if (rs[k])upd(rs[k],tag[k]);
27 tag[k]=make_pair(1,0);
28 }
29 void update(int &k,int l,int r,int x,int y,int z){
30 if ((l>y)||(x>r))return;
31 if (!k){
32 k=++V;
33 tag[k]=make_pair(1,0);
34 }
35 if ((x<=l)&&(r<=y)){
36 tag[k].fi=(tag[k].fi+z)%mod;
37 return;
38 }
39 down(k);
40 update(ls[k],l,mid,x,y,z);
41 update(rs[k],mid+1,r,x,y,z);
42 }
43 int query(int k,int l,int r,int x){
44 if (l==r)return tag[k].se;
45 down(k);
46 if (x<=mid)return query(ls[k],l,mid,x);
47 return query(rs[k],mid+1,r,x);
48 }
49 int merge(int k1,int k2){
50 if ((!k1)||(!k2))return k1+k2;
51 if ((!ls[k1])&&(!rs[k1]))swap(k1,k2);
52 if ((!ls[k2])&&(!rs[k2])){
53 upd(k1,make_pair(tag[k2].se,0));
54 return k1;
55 }
56 down(k1);
57 down(k2);
58 ls[k1]=merge(ls[k1],ls[k2]);
59 rs[k1]=merge(rs[k1],rs[k2]);
60 return k1;
61 }
62 void dfs(int k,int fa,int sh){
63 s[k]=sh;
64 if (!v[k].size())update(r[k],0,n,0,s[k],1);
65 else{
66 for(int i=1;i<v[k].size();i++)
67 if (s[v[k][i]]>s[v[k][0]])v[k][0]=v[k][i];
68 update(r[k],0,n,s[v[k][0]],s[k],mod-1);
69 }
70 for(int i=head[k];i!=-1;i=edge[i].nex)
71 if (edge[i].to!=fa){
72 dfs(edge[i].to,k,sh+1);
73 r[k]=merge(r[k],r[edge[i].to]);
74 }
75 if (k>1)update(r[k],0,n,0,s[k],query(r[k],0,n,s[k]));
76 }
77 int main(){
78 freopen("destiny.in","r",stdin);
79 freopen("destiny.out","w",stdout);
80 scanf("%d",&n);
81 memset(head,-1,sizeof(head));
82 for(int i=1;i<n;i++){
83 scanf("%d%d",&x,&y);
84 add(x,y);
85 add(y,x);
86 }
87 scanf("%d",&m);
88 for(int i=1;i<=m;i++){
89 scanf("%d%d",&x,&y);
90 v[y].push_back(x);
91 }
92 dfs(1,0,0);
93 printf("%d",query(r[1],0,n,0));
94 return 0;
95 }

[loj3340]命运的更多相关文章

  1. 一个页面实例化两个ueditor编辑器,同样的出生却有不同的命运

    今天遇到一个比较怪异的问题,有一项目需要在同一个页面上展现两个ueditor编辑器,在展现时并不任何问题,但当点击了“保存”按钮时就出错了,有其中一个ueditor在asp.net中无法获取编辑器的值 ...

  2. HDU 2571 命运

    命运 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submissi ...

  3. HDUOJ----2571(命运)(简单动态规划)

    命运 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submiss ...

  4. HDU 2571 命运 动态规划

    命运 http://acm.hdu.edu.cn/showproblem.php?pid=2571 Problem Description 穿过幽谷意味着离大魔王lemon已经无限接近了!可谁能想到, ...

  5. HDU 2571 命运 (DP)

    命运 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Pr ...

  6. hdu2571 命运 动态规划Dp

    转载请注明出处:http://blog.csdn.net/u012860063 题目链接:pid=2571" target="_blank">http://acm. ...

  7. HDU-2571命运

    Problem Description 穿过幽谷意味着离大魔王lemon已经无限接近了!可谁能想到,yifenfei在斩杀了一些虾兵蟹将后,却再次面临命运大迷宫的考验,这是魔王lemon设下的又一个机 ...

  8. 命运(HDU 2571 简单动态规划)

    命运 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submissi ...

  9. hdu 2571 命运(dp)

    Problem Description 穿过幽谷意味着离大魔王lemon已经无限接近了! 可谁能想到,yifenfei在斩杀了一些虾兵蟹将后,却再次面临命运大迷宫的考验,这是魔王lemon设下的又一个 ...

随机推荐

  1. Geostatistical Analyst Tools(Geostatistical Analyst 工具)

    Geostatistical Analyst 工具 1.使用地统计图层 # Process: GA 图层至格网 arcpy.GALayerToGrid_ga("", 输出表面栅格, ...

  2. 技术番外篇丨Github Action CI/CD

    起源 看到.Net群里再聊CI/CD,我就这里分享一下我目前自己一些小东西的做法,我目前在Github有一个自己私有的组织,里面存放了我的部分商业化项目,早期我采用Jenkins用Webhooks进行 ...

  3. 一个神秘的oj2093 花园的守护之神(最小割)

    给定一张无向图,你每次可以将一条路的权值增加1,询问最少增加多少次才会使得\(s->t\)的最短路改变 QwQ一看到这个题,我就用种最小割的感觉 我们可以把最短路上的点取出来,然后做最小割呀!! ...

  4. Vuls 漏洞扫描工具部署及效果展示

    Vuls 漏洞扫描工具部署及效果展示 介绍 Vuls根据NVD,OVAL等数据对主流Linux系统进行扫描,并具有完善的报告. 支持系统 Distribution Release Alpine 3.3 ...

  5. perl Encode模块的使用

    编码问题是广泛存在的,只有正确的编码才能在不同的地方正确的显示内容.而在数据的获取和转移过程中,编码经常是很需要注意的问题.perl有功能很好的编码处理模块Encode.在程序里简单的use Enco ...

  6. 使用寄存器点亮LED——2

    1. 项目:使用stm32寄存器点亮LED, 分别点亮红.绿.蓝3个灯. 2. 步骤 先新建个文件夹保存项目 再新建项目 将startup_stm32f10x_hd.s拷贝到该文件夹下 新建main. ...

  7. 【c++ Prime 学习笔记】第8章 IO库

    C++语言不直接处理输入输出,而是通过标准库中的一组类来处理IO 1.2节介绍的IO库: istream(输入流)类型,提供输入 ostream(输出流)类型,提供输出 cin,是istream对象, ...

  8. kivy Label触发事件

    kivy  label也可以触发事件,为什么只有我这么无聊学垃圾kivy """ 在通过ref标记一段文本后点击这段文本就可以触发'on_ref_press'事件,在该事 ...

  9. Noip模拟50 2021.9.10

    已经好长时间没有考试不挂分的良好体验了... T1 第零题 开场数据结构,真爽 对于这道题首先要理解对于一条链从上向下和从下向上走复活次数相等 (这可能需要晚上躺在被窝里面脑摸几种情况的样例) 然后就 ...

  10. Java并发:重入锁 ReentrantLock(一)

    ReentrantLock 是一种可重入的互斥锁,它不像 synchronized关键字一样支持隐式的重进入,但能够使一个线程(不同的方法)重复对资源的重复加锁而不受阻塞. ReentrantLock ...