当前位置:网站首页>P6773 [noi2020] destiny (DP, segment tree merging)
P6773 [noi2020] destiny (DP, segment tree merging)
2022-07-01 01:51:00 【wind__ whisper】
Preface
It looks like a cancer, but it's actually a small and fresh problem ?
It's not that difficult to understand .
Violence is very strong , Praise .
Wonderful line segment tree merging skills have been added .
analysis
solution 1
How do you play with your hands ?
Most of the ( For example, I ) All inclusive .
Move the method of playing to the code, and you get a question that the author wants us to write from the data range O ( 2 m p o l y ) O(2^mpoly) O(2mpoly) practice .
Think about it carefully. The tree can maintain the number of edges that are not covered ,dfs Modify it by the way , Time complexity O ( 2 m log 2 n ) O(2^m\log ^2n) O(2mlog2n).
Expected score 32-40 branch . I don't understand why it's written online O ( 2 m m log 2 n ) O(2^mm\log ^2n) O(2mmlog2n) ah
solution 2
You don't really write solutions 1 Is that right .
The form of this question is very dp.
Design f x , d f_{x,d} fx,d Representation node x x x The subtree of is processed , The maximum depth of the ancestor of the unresolved atavism chain is d d d Number of alternatives .
It is easy to transfer in the form of a backpack on a tree , Time complexity O ( n min ( n , m ) ) O(n\min(n,m)) O(nmin(n,m)), Expected score 64 64 64 branch . But the crap I wrote can't make a complete binary tree , The result is only 56 56 56 Divide up ( sad ).
( Prefixes and optimizations are easier to write , And then we can introduce the following positive solution )
solution 3
Observe dp Transfer , It is found that the transfer is very regular , It seems that you can maintain a segment tree and so on .
Then garbage, I can't think of segment tree merging , You can only think of maintaining a segment tree for each heavy chain after the heavy chain is divided , The subscript only stores the depth limit in the subtree ( Similar to discretization ), So the sum of the leaves of all segment trees is O ( n log n ) O(n\log n) O(nlogn), After the heavy chain is handled, the violence merges with the chain head father , Probably O ( n log 2 n ) O(n\log^2n) O(nlog2n) Of .
Expected score 88 branch .
It is very simple to realize , So just Hu Hu , It didn't write .
If it's fake, spray it gently ( flee
Gorgeous dividing line . Then my level is stuck in this place .
The next step is to solve the problem .
solution 4
hold dp The transfer is written in prefix and form :
d p x , i = d p x , i ′ ∑ j = 0 d e p x d p s , j + d p x , i ′ ∑ j = 0 i d p s , j + d p s , i ∑ j = 0 i − 1 d p x , j dp_{x,i}=dp'_{x,i}\sum_{j=0}^{dep_x}dp_{s,j}+dp'_{x,i}\sum_{j=0}^{i}dp_{s,j}+dp_{s,i}\sum_{j=0}^{i-1}dp_{x,j} dpx,i=dpx,i′j=0∑depxdps,j+dpx,i′j=0∑idps,j+dps,ij=0∑i−1dpx,j
That is to say :
d p x , i = d p x , i ′ ( s u m s , d e p x + s u m s , i ) + d p s , i s u m x , i − 1 dp_{x,i}=dp'_{x,i}(sum_{s,dep_x}+sum_{s,i})+dp_{s,i}sum_{x,i-1} dpx,i=dpx,i′(sums,depx+sums,i)+dps,isumx,i−1
Notice that in addition to s u m s , d e p x sum_{s,dep_x} sums,depx Is a constant , Everything else is closely related to subscripts .
Consider line segment tree merging .
Make s 1 = s u m s , d e p x + s u m s , i , s 2 = s u m x , i − 1 s1=sum_{s,dep_x}+sum_{s,i},s2=sum_{x,i-1} s1=sums,depx+sums,i,s2=sumx,i−1.
Recurse the left subtree before merging , In recursive right subtree , Constantly updated s 1 , s 2 s1,s2 s1,s2 that will do .
I think it's easier for you to understand the code than to listen to me .
ll s1,s2;
int merge(int x,int y,int l,int r){
if(!x&&!y) return 0;
else if(!x||!y){
if(x){
add(s2,tr[x].sum);
Mul(x,s1);
return x;
}
else{
add(s1,tr[y].sum);
Mul(y,s2);
return y;
}
}
else if(l==r){
int now=New();
int a=tr[x].sum,b=tr[y].sum;
add(s1,b);
tr[now].sum=(s1*a+s2*b)%mod;;
add(s2,a);
return now;
}
pushdown(x);pushdown(y);
int now=New();
tr[now].ls=merge(tr[x].ls,tr[y].ls,l,mid);
tr[now].rs=merge(tr[x].rs,tr[y].rs,mid+1,r);
pushup(now);
return now;
}
Then the problem is finished .
Complexity of time and space O ( n log n ) O(n\log n) O(nlogn), Expected score 100 branch .
Code
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("ok\n")
inline ll read(){
ll x(0),f(1);char c=getchar();
while(!isdigit(c)) {
if(c=='-')f=-1;c=getchar();}
while(isdigit(c)) {
x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*f;
}
const int N=5e5+100;
const int inf=1e9+100;
const int mod=998244353;
const bool Flag=0;
#define add(x,y) (((x)+=(y))>=mod&&((x)-=mod))
int n,m;
#define mid ((l+r)>>1)
struct node{
int ls,rs;
ll sum,mul=1;
}tr[N*40];
int tot;
vector<int>e[N];
inline int New(){
tr[++tot].mul=1;
return tot;
}
inline void Mul(int x,int w){
if(x){
tr[x].sum=tr[x].sum*w%mod;
tr[x].mul=tr[x].mul*w%mod;
}
return;
}
inline void pushdown(int x){
if(tr[x].mul!=1){
Mul(tr[x].ls,tr[x].mul);
Mul(tr[x].rs,tr[x].mul);
tr[x].mul=1;
}
return;
}
inline void pushup(int k){
tr[k].sum=(tr[tr[k].ls].sum+tr[tr[k].rs].sum)%mod;
}
ll ask(int k,int l,int r,int x,int y){
if(!k) return 0;
if(x<=l&&r<=y) return tr[k].sum;
pushdown(k);
ll res(0);
if(x<=mid) add(res,ask(tr[k].ls,l,mid,x,y));
if(y>mid) add(res,ask(tr[k].rs,mid+1,r,x,y));
return res;
}
ll s1,s2;
int merge(int x,int y,int l,int r){
//if(l>lim) return 0;
if(!x&&!y) return 0;
else if(!x||!y){
if(x){
add(s2,tr[x].sum);
Mul(x,s1);
return x;
}
else{
add(s1,tr[y].sum);
Mul(y,s2);
//printf("(%d %d) s2=%lld sum=%lld\n",l,r,s2,tr[y].sum);
return y;
}
}
else if(l==r){
int now=New();
int a=tr[x].sum,b=tr[y].sum;
add(s1,b);
tr[now].sum=(s1*a+s2*b)%mod;;
add(s2,a);
return now;
}
pushdown(x);pushdown(y);
int now=New();
tr[now].ls=merge(tr[x].ls,tr[y].ls,l,mid);
tr[now].rs=merge(tr[x].rs,tr[y].rs,mid+1,r);
pushup(now);
return now;
}
void ins(int &k,int l,int r,int p){
if(!k) k=New();
if(l==r){
tr[k].sum++;
return;
}
pushdown(k);
if(p<=mid) ins(tr[k].ls,l,mid,p);
else ins(tr[k].rs,mid+1,r,p);
pushup(k);
}
void print(int k,int l,int r){
if(!k) return;
if(l==r){
printf("d=%d dp=%lld\n",l,tr[k].sum);
return;
}
pushdown(k);
print(tr[k].ls,l,mid);
print(tr[k].rs,mid+1,r);
return;
}
int rt[N];
int dep[N],d[N];
void init(int x,int fa){
dep[x]=dep[fa]+1;
for(int to:e[x]){
if(to==fa) continue;
init(to,x);
}
return;
}
void dfs(int x,int fa){
for(int to:e[x]){
if(to==fa) continue;
dfs(to,x);
}
ins(rt[x],0,n,d[x]);
for(int to:e[x]){
if(to==fa) continue;
s1=ask(rt[to],0,n,0,dep[x]);
s2=0;
rt[x]=merge(rt[x],rt[to],0,n);
//printf("----------%d->%d\n",x,to);
//print(rt[x],0,n);
//puts("");
}
return;
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
n=read();
for(int i=1;i<n;i++){
int x=read(),y=read();
e[x].push_back(y);
e[y].push_back(x);
}
init(1,0);
m=read();
for(int i=1;i<=m;i++){
int u=read(),v=read();
d[v]=max(d[v],dep[u]);
}
dfs(1,0);
printf("%lld\n",ask(rt[1],0,n,0,0));
return 0;
}
边栏推荐
- 求两个线段公共部分的长度
- What will Web3 bring in the future?
- 工作八年的程序员,却拿着毕业三年的工资,再不开窍就真晚了...
- Gin configuration file
- MYSQL 数据库查看磁盘占用情况
- C#生成putty格式的ppk文件(支持passphrase)
- CorelDRAW 2022中文精简64位直装版下载
- Live shopping mall source code, realize left-right linkage of commodity classification pages
- 小程序中实现excel数据的批量导入
- What are the preferential activities for stock account opening? In addition, is it safe to open a mobile account?
猜你喜欢
Short message sending solution in medical his industry
Connectivity basis of Graphs
Batch import of Excel data in applet
Creating ASCII art with C #
How to maintain efficient collaboration in remote office and achieve stable growth of projects | community essay solicitation
zabbix如何配置告警短信?(预警短信通知设置流程)
Sitge joined the opengauss open source community to jointly promote the ecological development of the database industry
Electron pit Addon
(翻译)实时内联验证更容易让用户犯错的原因
Neo4j installation, operation, project construction and function realization
随机推荐
对象与对象变量
Sun Yuchen told Swiss media Bilan that the bear market will not last long
【agora】用户管理
Short video platform development, relying on drawerlayout to achieve side sliding menu effect
FL Studio20.9水果软件高级中文版电音编曲
Check the disk usage of MySQL database
Log4j2 threadcontext log link tracking
视频教程 | 长安链推出系列视频教程合集(入门)
More pragmatic in business
Test essential tool - postman practical tutorial
测试必备工具—Postman实战教程
The whole process of AS400 API from zero to one
opencv -- 笔记
Electron pit Addon
修复表中的名字(首字符大写,其他小写)
Mathematical knowledge: finding combinatorial number III - finding combinatorial number
Laravel event & subscription
In the fourth week of June, the list - flying melon data up main growth ranking list (BiliBili platform) was released!
【JS给元素添加属性:setAttribute;classList.remove;classList.add;】
Winodws 快速添加开机启动项