首页 > 其他分享 >P10145 [WC/CTS2024] 线段树 题解

P10145 [WC/CTS2024] 线段树 题解

时间:2024-02-06 11:56:05浏览次数:33  
标签:WC rs int 题解 tr ls CTS2024 集合 dp

Link

纪念一下场切题。

题意:给定一棵(分点不一定为中点)的线段树,给定若干个询问区间,问有多少个线段树上结点的集合,知道了这些结点对应的区间和就可以知道任何一个询问区间的和。


从询问区间开始考虑。会发现可以把所有 \(a_i\) 分成若干个集合,只要知道每个集合的和就可以知道所有询问区间的和。具体地,“被覆盖情况”相同的 \(a_i\) 是在同一个集合中的。特别的,可能有一些 \(a_i\) 没有被任何询问区间覆盖,这些 \(a_i\) 分到一个集合,它们的和可以不用求出。这个集合具体的分法可以用一个哈希处理,给每个区间赋一个权值,区间中每个点加上这个权值,就可以认为权值相同的点属于一个集合。

再考虑到线段树上的区间。可以认为我们标记了一些节点,知道了它们对应区间的和。同样的,通过上面的分类方法可以把所有 \(a_i\) 拆成若干个集合,知道了每个集合的和(以及有一个集合不知道)。进一步地,利用这个树形结构,会发现“祖先中自下而上第一个标记结点”相同的 \(a_i\) 是分在同一个集合里的。

考虑两组分类的关系。我们需要满足询问,所以第一种分类方式中不同集合的两个 \(a_i\) 在第二种分类方式中不能分在同一集合。也就是说第一组集合进一步拆分得到了第二组集合。容易发现这个条件是充要的。

下面来考虑一下特殊性质。特殊性质相当于第一种分类方式有 \(n\) 个集合 \(\{1\},\{2\},\cdots,\{n\}\),它们的和都需要知道。从刚才说明的第二种分类的判断方法入手,考虑做一个树形 DP,自下而上确定。根据刚才的充要条件,对某个点 \(u\),确定了它的子树的选择情况后,子树内的所有 \(a_i\) 至多有一个的分类(即第一个祖先)还没有确定。 那么就可以设 \(f_u\) 表示子树 \(u\) 内所有 \(a_i\) 的分类都确定的方案数,\(g_u\) 表示子树 \(u\) 内有一个 \(a_i\) 的分类还没有确定的方案数。设 \(u\) 的左右儿子分别为 \(ls,rs\),有

\[f_{u}=2f_{ls}f_{rs}+f_{ls}g_{rs}+g_{ls}f_{rs} \]

\[g_{u}=f_{ls}g_{rs}+g_{ls}f_{rs} \]

初始值是对于叶子结点 \(v\),\(f_v=g_v=1\)。答案是 \(f_{1}\)。这样就可以通过特殊性质。

再来处理一般情况。容易把刚才的性质推广:一棵子树完全确定后,至多有一类结点的分类(第一个祖先)还没有确定。那么就可以设计一个二维DP:\(dp_{u,i}\) 表示子树 \(u\) 内的方案确定后,第 \(i\) 个集合的点的分类还没有确定。特别地,\(i=0\) 表示都已经确定,\(i=1\) 表示这一类的和可以不用求,也就是它们可以没有“第一个标记的祖先”。转移为

\[dp_{u,i}=dp_{ls,0}dp_{rs,i}+dp_{ls,i}dp_{rs,0}+dp_{ls,i}dp_{rs,i} \]

\[dp_{u,0}=2dp_{ls,0}dp_{rs,0}+\sum dp_{u,i} \]

初始值是对于叶子结点 \(v\),如果它在第 \(i\) 类,有 \(dp_{v,0}=dp_{v,i}=1\)。答案是 \(dp_{1,0}+dp_{1,1}\)。直接做这个 DP,复杂度是 \(O(n\times\min(n,m))\),结合特殊性质可以获得 \(85\) 分。

最后 \(15\) 分,只需要记录 \(dp_u\) 中每个非零数,做启发式合并即可。具体的,需要维护一个乘法标记,以及 \(\sum_{i\neq 0} dp_{u,i}\)。使用 map 实现,时间复杂度是 \(O(n\log^2 n)\)。

中间有一步除法,可能遇到除以 \(0\) 的情况,所以需要特殊处理(是容易的)。场上当然没有考虑到,不过良心出题人 jiangly 在 WC 的数据里并没有卡,赞美良心出题人!

代码是赛后补的。

#include<bits/stdc++.h>
using namespace std;
mt19937 rnd(time(0));
const int N=4e5+5,P=998244353;
int qpow(int a,int b=P-2){
    int c=1;
    for(;b;b>>=1,a=1ll*a*a%P)
        if(b&1)c=1ll*c*a%P;
    return c;
}
int n,m,tot=1,h[2][N],typ[N];
struct node{int ls,rs,l,r;}tr[N];
void build(int p,int l,int r){
    tr[p].l=l;tr[p].r=r;
    if(l==r)return;
    int mid;scanf("%d",&mid);
    tr[p].ls=++tot;build(tot,l,mid);
    tr[p].rs=++tot;build(tot,mid+1,r);
}
vector<pair<int,int> > vec;
map<int,int> dp[N];int to[N],mul[N],sum[N];
int main(){
    scanf("%d%d",&n,&m);build(1,1,n);
    for(int i=1,l,r;i<=m;i++){
        scanf("%d%d",&l,&r);++l;++r;
        int v0=rnd()%P,v1=rnd()%P;
        h[0][l]=(h[0][l]+v0)%P;h[0][r]=(h[0][r]+P-v0)%P;
        h[1][l]=(h[1][l]+v1)%P;h[1][r]=(h[1][r]+P-v1)%P;
    }
    for(int i=1;i<=n;i++){
        h[0][i]=(h[0][i]+h[0][i-1])%P;
        h[1][i]=(h[1][i]+h[1][i-1])%P;
        vec.push_back({h[0][i],h[1][i]});
    }
    vec.push_back({0,0});sort(vec.begin(),vec.end());
    for(int i=1;i<=n;i++)typ[i]=lower_bound(vec.begin(),vec.end(),
        make_pair(h[0][i],h[1][i]))-vec.begin()+1;
    for(int i=2*n-1;i>=1;i--){
        if(!tr[i].ls){
            dp[i][0]=dp[i][typ[tr[i].l]]=1;
            to[i]=i;mul[i]=sum[i]=1;continue;
        }
        int x=to[tr[i].ls],y=to[tr[i].rs];
        if(dp[x].size()<dp[y].size())swap(x,y);
        int vl=dp[x][0],vr=dp[y][0];to[i]=x;
        mul[x]=1ll*mul[x]*mul[y]%P*vr%P;
        dp[x][0]=(vl+vl)%P;
        for(auto it:dp[y]){
            int c=it.first,f=it.second;
            if(c==0)continue;int&g=dp[x][c];
            int tmp=1ll*f*(g+vl)%P*qpow(vr)%P;
            g=(g+tmp)%P;sum[x]=(sum[x]+tmp)%P;
        }
        dp[x][0]=(dp[x][0]+sum[x])%P;
    }
    int ans=(dp[to[1]][0]+dp[to[1]][1])%P;
    ans=1ll*ans*mul[to[1]]%P;
    printf("%d\n",ans);
    return 0;
}

标签:WC,rs,int,题解,tr,ls,CTS2024,集合,dp
From: https://www.cnblogs.com/by-chance/p/18009481

相关文章

  • 浅谈甲类生产厂房应急照明和疏散指示系统的设计问题解析
    摘要:文章结合电气设计项目实践经验,分析了甲类生产厂房消防应急照明和疏散指示系统设计中照明灯和标志灯的设置、疏散走道和疏散通道的规划、集中控制型系统类型的选择、电压等级的选择中存在的问题,总结了相关经验,可以为同类工程提供参考。关键词:甲类生产厂房;消防应急照明和疏散指示......
  • 2024 NOIWC 游记
    复盘前天晚上去试机,调了一下Geany的配置。这玩意确实好用,很合我胃口。进赛场,发现给了吃的和牛奶,非常良心啊。PKUWC甚至没有清试机留下来的东西,WC清掉了,比较可惜。先看题。看T1,不会。看T2,感觉比较可做。看T3,这是啥玩意??于是开始想T2。发现了一些性质,注意到一个区间在\(L......
  • WC2024 水镜
    洛谷传送门WC2024被打爆了,呜呜。我赛时会这题\(8\)分指数级暴力,哈哈。真不知道自己在干嘛。下文令\(T=2L\)。考虑如何判定一个序列\(a\)是否合法。考虑先枚举一个\(T\)。因为要求\(r_i<r_{i+1}\),考虑讨论相邻两项的取值:若\(a_i<a_{i+1}\)则\(r_i=a_i,......
  • WC2024 游记
    2月1日测试开场读三道题,题好长!T1看起来是数数,T2是神秘构造,T3还是数数。开赛后15分钟开始想T1。直接做好像不太可做啊,然后立刻想到了拆贡献看看。发现拆贡献后问题变成了背包问题,可以\(\mathcalO(nT)\)解决。看完数据范围有点惊讶,我的做法能拿满分!在去年,金牌分数线不......
  • 题解 CF1876B
    题意给定一个数组\([a_1,a_2,a_3.\cdots,a_n]\),一开始所有元素都为白色。你可以选定其中的至少一个元素涂成黑色,共有\(2^n-1\)种涂法。此时对于所有黑色元素\(a_i\),下标为\(i\)的倍数的所有白色元素都将变成绿色。此时数组中所有黑色和绿色元素的最大值记为此种涂法的......
  • 洛谷 P10145 [WC/CTS2024] 线段树 题解--zhengjun
    提供一种考场做法,在思路上和官方题解的差异蛮大的,虽然结果差不多。首先需要发现\([l,r)\)区间可以算出来的充要条件是:如果对于每个选中的节点\(u\),连无向边\((L_u,R_u)\),则当且仅当\(l\)和\(r\)连通时区间\([l,r)\)可以算出来。证明的话,用前缀和理解这些东西,分别考虑......
  • 题解 CF1849D
    萌新的第一篇题解题目大意对于一个初始颜色都为蓝色的数组\(a_1,a_2,\dots,a_n\)其中\(a_n\in\{0,1,2\}\),现在可以进行两个操作:花费\(1\)个金币,将\(a_i\)涂成红色;选择一个红色的\(a_i>0\),将\(a_{i-1}\)或\(a_{i+1}\)涂成红色,同时\(a_i\)减\(1\)。输出金......
  • F. 乘积最大(题解)
    题目今年是国际数学联盟确定的“2000——世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰90周年。在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友XZ也有幸得以参加。活动中,主持人给所有参加活动的选手出了这样一道题目:设有一个长度为......
  • [ARC135D] Add to Square 题解
    题目链接点击打开链接题目解法很牛的题!!!先考虑一步很牛的转化:把矩阵黑白染色,且\(i+j\)为奇数的位置的值取反,每次操作变为左上右下\(+v\),左下右上\(-v\)这样有啥好处?操作不会使行和列的和改变考虑答案的下界显然是:\(\max\{\)行的绝对值之和,列的绝对值之和\(\}\)这里给出......
  • luogu2647题解
    首先这道题没有规定选几个。一开始我以为是全选,然后想了个贪心才发现看错了。那我们先来假设选\(m\)个。这个题的每个物品都会影响后面物品的收益,不好看。由于每个物品\(i\)对后选的其他物品减少的收益都是\(R_i\),因此我们在保证总价值不变的情况下转化一下,把该物品的价......