容斥,强制若干条链不重要,即有$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. OGG-如何只同步最近某个时间范围的数据

    一.需求,某客户希望使用OGG只同步时间大于2021-02-01日期之后的数据变换 需求如标题所示,如何使用OGG进行配置? 客户环境需要同步的表有几百G,表数据太大了;如果同步所有数据,目标库空间存 ...

  2. Spring启动过程源码分析基本概念

    Spring启动过程源码分析基本概念 本文是通过AnnotationConfigApplicationContext读取配置类来一步一步去了解Spring的启动过程. 在看源码之前,我们要知道某些类的 ...

  3. 替换excel模板中的内容并使用JavaMail发送邮件

    由于在公司工作,常年出差,每天都要以日报的形式向公司汇报当天的工作内容.而日报的内容大体上就只有当天工作的主要内容时变化的,其余的都是不变 的. 而我的电脑刚打开excel有点卡,因此决定使用Java ...

  4. java中生成和验证jwt

    在这篇文章中主要记录一下在Java中如何使用 java 代码生成jwt token,主要是使用jjwt来生成和验证jwt,关于什么是JWT,以及JWT可以干什么不做详解. jwt的格式: base64 ...

  5. 用cmd命令行创建vue项目模板

    1.进入cmd命令行 输入存放项目的位置 2.通过vue create 项目名称 创建项目 3.选择Manually select features 4.通过空格选中第1.2.5.6.7.去掉8 4. ...

  6. QMake(Qt项目构建)

    qmake工具能够简化不同平台上的项目构建.可以自动产生Makefiles文件,仅仅需要少量的信息就可以生成Makefile文件.同时qmake也可以构建不是Qt的项目.qmake基于项目文件中的信息 ...

  7. LCA-离线tarjan模板

    /* *算法引入: *树上两点的最近公共祖先; *对于有根树的两个结点u,v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u,v的祖先且x的深度尽可能大; *对于x来说,从u到v的路径一定 ...

  8. jQuery中onload与ready区别

    onload和ready的区别document.ready和onload的区别为:加载程度不同.执行次数不同.执行速度不同.1.加载程度不同 document.ready:是DOM结构绘制完毕后就执行 ...

  9. Linux的inode与block

    1,inode包含文件的元信息,具体来说有以下内容: 文件的字节数 文件拥有者的User ID 文件的Group ID 文件的读.写.执行权限 文件的时间戳,共有三个:ctime指inode上次文件属 ...

  10. Ubuntu安装数据库

    1.通过命令行安装:sudo apt-get install mysql-client mysql-server 2.安装过程中输入数据库密码("123456",root) 3.使 ...