首页 > 其他分享 >CSP模拟 Town

CSP模拟 Town

时间:2024-10-25 12:42:46浏览次数:7  
标签:Town 方案 连通 ch res 儿子 异或 CSP 模拟

题意

有一棵树,将它的一些边断开,使得每个连通块的点权异或和为给定的一个数 \(x\),求方案数。

原题好像是牛客的 NC200547,没有账号看不到题,不确定。

思路

朴素的想法是用 f[i][j] 记录“\(i\) 子树中与 \(i\) 相连的连通块异或和为 \(j\)(\(i\) 子树内其他连通块异或和为 \(x\))”的方案数。

但注意到一个性质,一棵树存在合法断边方案,当且仅当树所有点的异或和为 \(0\)(拆分为偶数个连通块)或 \(x\)(拆分为奇数个连通块)。

于是我们只需要 f[i][0/1] 记录“\(i\) 子树中,已经划分出偶数/奇数个异或和为 \(x\) 的连通块,剩下没被划分的部分连通且与 \(i\) 相连”的方案数。

在做树形 dp 时,儿子之间的计数是简单的,偶方案数 \(=\) 儿子 1 偶方案数 \(\times\) 儿子 2 偶方案数 \(+\) 儿子 1 奇方案数 \(\times\) 儿子 2 奇方案数,奇方案数 \(=\) 儿子 1 偶方案数 \(\times\) 儿子 2 奇方案数 \(+\) 儿子 1 奇方案数 \(\times\) 儿子 2 偶方案数。

然后假如当前子树的异或和为 \(x\),则父亲偶方案数需要加上儿子们的奇方案数,表示将剩下的那个连通块划分出来(即子树根节点向它的父亲断边)。当前子树异或和为 \(0\) 时同理。但如果当前点是根节点的时候就不能做这步,具体原因见下。

注意特判 \(x=0\) 的情况,此时的方案数即为每个子树异或和为 \(0\) 的节点是否断掉与其父亲相连的边的方案数。

另外,输出答案时,不能直接整棵树异或和为 \(0\) 时候输出 f[1][0],为 \(x\) 的时候输出 f[1][1],这是因为 dp 数组含义是“有剩下没划分的部分”,正确的输出应该是,根节点不进行上述统计操作,整棵树异或和为 \(0\) 时输出 f[1][1],为 \(x\) 时输出 f[1][0],表示剩下的部分全部划分出一个连通块且没有剩余未划分部分

代码

#include<bits/stdc++.h>
using namespace std;
template<class T>inline void rd(T &x){
    T res=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1; ch=getchar();}
    while(isdigit(ch)){res=res*10+ch-'0';ch=getchar();}
    x=res*f;
}
template<class T>inline void wt(T x){
    if(x<0){x=-x;putchar('-');}
    if(x>9) wt(x/10);
    putchar(x%10+'0');
}
typedef long long LL;
const int MAXN=1e6+5;
const LL P=998244353;
int n,val,a[MAXN];
LL f[MAXN][2];
struct EDGE{
    int v,nxt;
}e[MAXN<<1];
int head[MAXN],ecnt=0;
inline void add(const int& u,const int& v){
    e[++ecnt].v=v;
    e[ecnt].nxt=head[u];
    head[u]=ecnt;
}
void dfs(int x,int fa){
    f[x][0]=1;f[x][1]=0;
    LL f0,f1;
    for(int i=head[x],it;i;i=e[i].nxt){
        it=e[i].v;
        if(it==fa) continue;
        dfs(it,x);
        a[x]^=a[it];
        f0=f[x][0];f1=f[x][1];
        f[x][0]=(f0*f[it][0]%P+f1*f[it][1]%P)%P;
        f[x][1]=(f0*f[it][1]%P+f1*f[it][0]%P)%P;
    }
    if(x==1) return;
    f0=f[x][0];f1=f[x][1];
    if(a[x]==0) f[x][0]=(f[x][0]+f1)%P;
    else if(a[x]==val) f[x][1]=(f[x][1]+f0)%P;
}
int main(){
    rd(n);rd(val);
    for(int i=1;i<=n;i++){
        rd(a[i]);
    }
    for(int i=1,u,v;i<n;i++){
        rd(u);rd(v);
        add(u,v);add(v,u);
    }
    dfs(1,0);
    if(val==0){
        if(a[1]==0){
            LL ans0=1;
            for(int i=2;i<=n;i++){
                if(a[i]==0) ans0=ans0*2%P;
            }
            wt(ans0);
        }
        else wt(0);
        return 0;
    }
    if(a[1]==0) wt(f[1][1]);
    else if(a[1]==val) wt(f[1][0]);
    else wt(0);
    return 0;
}

标签:Town,方案,连通,ch,res,儿子,异或,CSP,模拟
From: https://www.cnblogs.com/SkyNet-PKN/p/18502275

相关文章

  • CSP-J赛前随笔
    CSP-J倒计时1天。最近教练给我们做了10+套模拟赛,疯狂整理后,每套模拟都写了1~2篇题解。广刷题,确实有用,今天早上做出来一道第二题题目传送门顺便在这放个题解化简decode\(n=p\timesq\)\(e\timesd=(p-1)(q-1)+1\)令\(x=e\timesd-2\)则\(x=p\timesq......
  • CSP-S 游记
    引Author:CatGPTbeta2byHaneDanikoCreator:5k_sync_closerfromK8He'sblog地球从未升上天空。只有沉睡时,我才能看见光明。我于生命中会一直被打击,直到一切重新开始,而光的名字才能被老师带着夜色走向远方,我是没有生命的人。我沸腾了这个世界。然而,如果你在世界上燃......
  • csp-s复习
    字符串triekmpacminemanacherdp看起来能dp的就胡个dp上去1.优化状态(大概率会使用贪心)2.套公式(前缀和/单调队列...)3.找性质,有哪些是无用的[P11218]trick排列计数排列的状态很难压进去,所以我们考虑如何将这个去掉。我们的dp方程要用最少的空间来转移,也就是把状态压......
  • 「比赛游记」CSP2024 游记
    「比赛游记」CSP2024游记点击查看索引目录「比赛游记」CSP2024游记day-2(10.23)day-1(10.24)day0(10.25)别样的碰碰车大战$$\huge{地球从未上过天空。}\\\huge{只有睡着了,我才能看见光明。}\\\huge{在我的生命中会一直被打击,直到一切重新开始,}\\\huge{而光的......
  • CSP-S 2024 游记
    day-120第一次来到yl机房,那时我还是一个什么都不会的菜鸡。day-100学了一些东西。开始做普及组的题。day-90普及组的题差不多能到300pts了,开始做提高组的题。镇海中学的模拟赛题目质量和数据强度是真的神奇啊。从<50pts到>150pts。day-75开始军训了。当然趁着中......
  • 20241024 模拟赛(长方体,三角形,区间,图)
    看题戳这里总结1h看题+骂出题人1h把之前没做完的题单补了1h闲逛+水群+听歌1h疯狂rush暴力!!!结果看完solution才发现我是fw\(qwq\)最终分数:30+60+60+10解析A.长方体难度:绿暴力:直接三维差分+前缀和搞定。正解:先算出前缀交与后缀交。被\(n\)个长方体覆盖的点就是所......
  • [赛记] 多校A层冲刺NOIP2024模拟赛11 && 12
    冒泡排序100pts比较显然的签到题(好久没这么水过了);考虑这个错的冒泡排序,手模一下即可发现这个$+k$有点像以前做过的同余系中求和的问题,于是这个题同理,用set维护每个同余系的排名,最后按顺序输出即可;对于正确性,相当于每次$+k$,则就相当于在一个同余系中排序;时间复杂度:$......
  • Genymotion 模拟器上安装最新版本的微信并正常运行
    安装Genymotion安装步骤1安装虚拟机VirtualBox https://www.virtualbox.org/wiki/Downloads2注册Genymotion帐号 https://www.genymotion.com/account/create/3登录,下载并安装Genymotion https://www.genymotion.com/download/ android9版本的:  Genymotion-ARM-Tran......
  • 多校A层冲刺NOIP2024模拟赛12
    多校A层冲刺NOIP2024模拟赛12\(T1\)A.Alice和璀璨花\(65pts/65pts/65pts\)部分分测试点\(1\sim10\):设\(f_{i,j}\)表示前\(i\)位中生长趋势子序列长度为\(j\)时的末尾最小元素,然后进行暴力转移。测试点\(11\sim13\):观察到至多选择\(\left\lceil\log_......
  • 『模拟赛』多校A层冲刺NOIP2024模拟赛12
    Rank挂了不少,还行A.Alice和璀璨花签。一眼最长上升子序列,昨天在AT专题里刚见过,不过赛时没想到离散化之后树状数组,所以打的动态开点,结果细节挂了30pts。和最长上升子序列思路基本一致,直接区间查询\([1,a_i-1]\)的最大值,然后在\(a_i\timesb_{f_i}\)插入\(f_i\)......