容斥,强制若干条链不重要,即有$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. CefSharp请求资源拦截及自定义处理

    CefSharp请求资源拦截及自定义处理 前言 在CefSharp中,我们不仅可以使用Chromium浏览器内核,还可以通过Cef暴露出来的各种Handler来实现我们自己的资源请求处理. 什么是资源 ...

  2. Django对表单进行增删改查

    查 首先在url中写好路径 其次在后面参数的views里写函数类xxxxxxx的基本逻辑 定义一个函数xxxxxxx,继承request,注意这个request对数据库操作结果都会存放在request ...

  3. 洛谷3809 SA模板 后缀数组学习笔记(复习)

    其实SA这个东西很久之前就听过qwq 但是基本已经忘的差不多了 嘤嘤嘤 QWQ感觉自己不是很理解啊 所以写不出来那种博客 QWQ只能安利一些别人的博客了 小老板 真的是讲的非常好 不要在意名字 orz ...

  4. 配置pyenv环境

    git clone https://github.com/pyenv/pyenv.git ~/.pyenv echo 'export PYENV_ROOT="$HOME/.pyenv&quo ...

  5. Noip模拟36 2021.8.11

    刚题的习惯还是改不了,怎么办??? T1 Dove打扑克 考场上打的动态开点线段树+并查集,考后发现自己像一个傻子,并查集就行.. 这几天恶补数据结构疯了 用树状数组维护后缀和,$siz_i$表示编号 ...

  6. 种类并查集(维护敌人的敌人是朋友)、并行-poj1182-食物链 笔记

    题意 输入若干组数据,代表着不同动物在食物链的位置(A,B,C),要求出在输入的过程中有多少组数据会与之前矛盾. 思路(借鉴挑战程序设计竞赛) 这题是学并查集时的题,所以用了并查集. 一开始我想的是, ...

  7. AtCoder Beginner Contest 182 F

    F - Valid payments 简化题意:有\(n\)种面值的货币,保证\(a[1]=1,且a[i+1]是a[i]的倍数\). 有一个价格为\(x\)元的商品,付款\(y\)元,找零\(y-x\ ...

  8. Swift-技巧(一)缩放并填充图片

    摘要 直接操作图片来实现它的缩放或者填充多余空间,首选 UIGraphicsBeginImageContext 函数来实现,它就相当于一个画布,你甚至可以用它来涂鸦. 最近有一个需求,就是将图片先等比 ...

  9. 使用.NET6打造动态API

    ApiLite是直接将Service层自动生成api路由,可以不用添加Controller,支持模块插件化,在项目开发中能够提高工作效率,降低代码量. 开发环境 .NET SDK 6.0.100-rc ...

  10. 前端---梳理 http 知识体系 1

    最近看了http相关的知识点,觉得还是有必要整理下,这样对自己的网络知识体系也有帮助. http 是什么 http叫超文本传输协议,可以拆成超文本.传输.协议来理解 协议 http 是一个用在计算机里 ...