[BZOJ 3553][SHOI2014]三叉神经树

传送门(下面也有题面)

题目大意:

  一颗有根树,每个非叶子节点都有三个子节点,每个节点的权为0/1。

  每个节点的权 取决于其所有子节点中 哪种权出现的次数更多。

  有若干次询问,每次询问修改一个叶子节点的权,然后输出修改后根节点的权。

  给出叶子节点初始值。

 

解法:树链剖分+线段树

  叶子节点和非叶子节点的性质不同,为了省却麻烦,我们把叶子节点去掉,

  每次修改叶子节点就直接修改其父亲。以下的“叶子节点”均指处理后的树的叶子节点。

  如果用num[]记录每个节点的权为1的子节点个数,

  那么当num[i]>1时,点i权为1;当num[i]<=1时,权为0。

  记fa[i]表示i节点的父亲节点。

  可以推出:

    当num[i]=1时num[i]++,那么num[fa[i]]++;

    当num[i]=2时num[i]--,那么num[fa[i]]--;

  于是就有一个暴力算法,如果修改的当前点的num满足条件,就向上修改。

  其实就相当于使从根到叶子节点的链上最后一个num!=1(2)的点到叶子节点的区间权值+(-)1;

  然后就可以用树链剖分+线段树愉快的AC了。

代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define N ((1<<19)-1)
  4 
  5 int n,cnt;
  6 int fir[N],size[N],pt[N],pos[N],fa[N<<2],data[N<<2],ori[N];
  7 
  8 struct edge{
  9     int to,n;
 10     edge(){} edge(int _to,int _n){to=_to,n=_n;}
 11 };
 12 vector<edge>e;
 13 
 14 struct SN{
 15     int num,flag;
 16     SN*son[2];
 17 }sn[N<<2],*root;
 18 
 19 void putin()
 20 {
 21     int i,j,x;
 22     scanf("%d",&n);
 23     e.push_back(edge());
 24     for (i=1;i<=n;i++)
 25     for (j=0;j<3;j++)
 26     {
 27         scanf("%d",&x);
 28         fa[x]=i;
 29         if (x<=n) 
 30         {
 31             e.push_back(edge(x,fir[i]));
 32             fir[i]=e.size()-1;
 33         }
 34     }
 35 }
 36 
 37 void pre(int x)
 38 {
 39     size[x]=1;pt[x]=0;
 40     for (int i=fir[x];i;i=e[i].n)
 41     {
 42         pre(e[i].to);
 43         size[x]+=size[e[i].to];
 44         if (size[e[i].to]>size[pt[x]]) pt[x]=e[i].to;
 45     }
 46 }
 47 
 48 void getpath(int x)
 49 {
 50     pos[x]=++cnt;
 51     if (pt[x]) 
 52     {
 53         ori[pt[x]]=ori[x];
 54         getpath(pt[x]);
 55     }
 56     for (int i=fir[x];i;i=e[i].n)
 57     {
 58         if (e[i].to==pt[x]) continue;
 59         ori[e[i].to]=e[i].to;
 60         getpath(e[i].to);
 61     }
 62 }
 63 
 64 void build(SN&x,int l,int r)
 65 {
 66     x.flag=-1;
 67     if (l==r) return;
 68     x.son[0]=&sn[++cnt];
 69     x.son[1]=&sn[++cnt];
 70     int m=(l+r)>>1;
 71     build(*x.son[0],l,m);
 72     build(*x.son[1],m+1,r);
 73 }
 74 
 75 void update(SN&x)
 76 {
 77     for (int i=0;i<2;i++)
 78     {
 79         SN&z=*x.son[i];
 80         z.num=z.flag=x.flag;
 81     }
 82     x.flag=-1;
 83 }
 84 
 85 bool change(SN&x,int l,int r,int i,int j,int &p,int &v)
 86 {
 87     if (i<=l&&r<=j&&x.num==p)
 88     {
 89         x.num+=v;
 90         x.flag=x.num;
 91         return 0;
 92     }
 93     if (l==r)
 94     {
 95         x.num+=v;
 96         return 1;
 97     }
 98     if (x.flag!=-1) update(x);
 99     int m=(l+r)>>1;
100     bool re=0;
101     if (m<j) re=change(*x.son[1],m+1,r,i,j,p,v);
102     if (!re&&i<=m) re=change(*x.son[0],l,m,i,j,p,v);
103     x.num=-1;
104     if ((*x.son[0]).num==(*x.son[1]).num)x.num=(*x.son[0]).num;
105     return re;
106 }
107 
108 void work(int x)
109 {
110     int p,v;
111     if (data[x])
112     {
113         data[x]=0;
114         p=2,v=-1;
115     }
116     else 
117     {
118         data[x]=1;
119         p=1,v=1;
120     }
121     x=fa[x];
122     while (x)
123     {
124         if (change(*root,1,n,pos[ori[x]],pos[x],p,v)) return;
125         x=fa[ori[x]];
126     }
127 }
128 
129 void initialize()
130 {
131     int x;
132     for (int i=n+1;i<=3*n+1;i++)
133     {
134         scanf("%d",&x);
135         if (x) work(i);
136     }
137 }
138 
139 int SR(SN&x,int r)
140 {
141     if (r==1) return x.num;
142     if (x.flag!=-1) update(x);
143     return SR(*x.son[0],(1+r)>>1);
144 }
145 
146 void respond()
147 {
148     int q,x,temp;
149     scanf("%d",&q);
150     for (int i=0;i<q;i++)
151     {
152         scanf("%d",&x);
153         work(x);
154         temp=SR(*root,n);
155         if (temp>1) printf("%d\n",1);
156         else printf("%d\n",0);
157     }
158 }
159 
160 int main()
161 {
162     putin();
163     pre(1);
164     ori[1]=1;
165     getpath(1);
166     cnt=0;
167     root=&sn[0];
168     build(*root,1,n);
169     initialize();
170     respond();
171 }
BZOJ3553

 

说好的题面:

3553: [Shoi2014]三叉神经树

Time Limit: 160 Sec  Memory Limit: 256 MB

Description

计算神经学作为新兴的交叉学科近些年来一直是学术界的热点。一种叫做SHOI 的神经组织因为其和近日发现的化合物 SHTSC 的密切联系引起了人们的极大关注。
SHOI 组织由若干个 SHOI 细胞构成,SHOI 细胞之间形成严密的树形结构。
每个 SHOI 细胞都有且只有一个输出端,被称为轴突,除了一个特殊的、被称为根细胞的 SHOI 细胞的输出作为整个组织的输出以外,其余细胞的轴突均连向其上级 SHOI 细胞;并且有且只有三个接收端,被称为树突,从其下级细胞或者其它神经组织那里接收信息。SHOI 细胞的信号机制较为简单,仅有 0 和 1 两种。每个 SHOI 细胞根据三个输入端中 0 和 1 信号的多寡输出较多的那一种。
现在给出了一段 SHOI 组织的信息,以及外部神经组织的输入变化情况。请你模拟 SHOI 组织的输出结果。

Input

第一行一个整数:n。表示 SHOI 组织的总细胞个数。SHOI 细胞由 1~n 编号,编号为 1 的是根细胞。
从第二行开始的 n 行,每行三个整数 x1, x2, x3,分别表示编号为 1~n 的 SHOI 细胞的树突连接。1<xi≤n 表示连向编号为 xi 的细胞的轴突, n<xi≤3n+1 表示连向编号为 xi 的外界输入。输入数据保证给出的 SHOI 组织是合法的且所有的 xi 两两不同。
接下来一行 2n+1 个 0/1 的整数,表示初始时的外界输入。
第 n+3 行有一个整数:q,表示总操作数。
之后 q 行每行一个整数 x,表示编号为 x 的外界输入发生了变化。

Output

输出 q 行每行一个整数,对应第 i 次外界输入变化后的根细胞的输出。

Sample Input

3
2 3 4
5 6 7
8 9 10
0 0 0 0 1 1 1
5
4
4
5
6
8

Sample Output

1
0
0
1
1

HINT

对于 100%的数据,n≤500000,q≤500000。

转载于:https://www.cnblogs.com/KaNNeXFF/p/5503301.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值