[BZOI2014]大融合——————线段树进阶
竟然改了不到一小时就改出来了, 可喜可贺
Description

Solution
一开始想的是边两侧简单路径之和的乘积,之后发现这是个树形结构,简单路径数就是节点数。
之后的难点就变成了如何求线段树中不连续且无序区间中的权值。答案当然是没办法求
所以我们要进行离线,现将所有建边信息记录下来,把最终形成的树建好,然后在树上求DFS序。这样就能保证一个子树内的节点编号是连续的。
在查询时给出的两点一定具有父子关系,只需先找出二者中的儿子,之后求出它们所在树的节点树与儿子子树的节点树,做差后相乘即可。
CODE:

1 #include<bits/stdc++.h>
2 #define debug cout<<"lbwnb"
3 using namespace std;
4 const int NN=1e5+10;
5 int siz[NN],dep[NN],lin[NN],tmp,to[NN*2],n,q,rt[NN],x,y,fa[NN],dat[NN][3],nex[NN*2],head[NN],num;
6 char op[NN];
7 inline void add(int a,int b){
8 to[++num]=b; nex[num]=head[a]; head[a]=num;
9 to[++num]=a; nex[num]=head[b]; head[b]=num;
10 }
11 inline int getf(int x){
12 return fa[x]==x?x:fa[x]=getf(fa[x]);
13 }
14 inline int read(){
15 int x=0,f=1;
16 char ch=getchar();
17 while(ch<'0'||ch>'9'){
18 if(ch=='-') f=-1;
19 ch=getchar();
20 }
21 while(ch>='0'&&ch<='9'){
22 x=(x<<1)+(x<<3)+(ch^48);
23 ch=getchar();
24 }
25 return x*f;
26 }
27 void write(int x){
28 if(x<0) putchar('-'), x=-x;
29 if(x>9) write(x/10);
30 putchar(x%10+'0');
31 }
32 void dfs(int x){
33 lin[x]=++tmp; siz[x]=1;
34 for(int i=head[x];i;i=nex[i]){
35 int v=to[i];
36 if(dep[v]) continue;
37 dep[v]=dep[x]+1;
38 dfs(v);
39 siz[x]+=siz[v];
40 }
41 }
42 struct node{
43 int ls[NN*40],rs[NN*40],seg,sum[NN*40];
44 void pushup(int x){
45 sum[x]=sum[ls[x]]+sum[rs[x]];
46 }
47 void insert(int &x,int l,int r,int pos,int val){
48 if(!x) x=++seg;
49 if(l==r){ sum[x]+=val; return; }
50 int mid=(l+r)>>1;
51 if(pos<=mid) insert(ls[x],l,mid,pos,val);
52 else insert(rs[x],mid+1,r,pos,val);
53 pushup(x);
54 }
55 void merge(int &x,int y,int l,int r){
56 if(!x||!y){ x=x+y; return; }
57 if(l==r){ sum[x]+=sum[y]; return; }
58 int mid=(l+r)>>1;
59 merge(ls[x],ls[y],l,mid);
60 merge(rs[x],rs[y],mid+1,r);
61 pushup(x);
62 }
63 int query(int x,int l,int r,int opl,int opr){
64 if(l>=opl&&r<=opr) return sum[x];
65 int mid=(l+r)>>1,ret=0;
66 if(opl<=mid) ret+=query(ls[x],l,mid,opl,opr);
67 if(opr>mid) ret+=query(rs[x],mid+1,r,opl,opr);
68 return ret;
69 }
70 }segt;
71 int main(){
72 n=read(); q=read();
73 for(int i=1;i<=q;i++)
74 cin>>op[i]>>dat[i][1]>>dat[i][2];
75 for(int i=1;i<=q;i++)
76 if(op[i]=='A') add(dat[i][1],dat[i][2]);
77 for(int i=1;i<=n;i++)
78 if(!dep[i]) dep[i]=1,dfs(i);
79 for(int i=1;i<=n;i++)
80 segt.insert(rt[i],1,n,lin[i],1), fa[i]=i;
81 for(int i=1;i<=q;i++){
82 if(op[i]=='A'){
83 int r1=getf(dat[i][1]), r2=getf(dat[i][2]);
84 segt.merge(rt[r1],rt[r2],1,n);
85 fa[r2]=r1;
86 }
87 if(op[i]=='Q'){
88 int son=dep[dat[i][1]]>dep[dat[i][2]]?dat[i][1]:dat[i][2];
89 int ro=getf(dat[i][1]);
90 int tot=segt.query(rt[ro],1,n,1,n),sot=segt.query(rt[ro],1,n,lin[son],lin[son]+siz[son]-1);
91 write((tot-sot)*sot); putchar('\n');
92 }
93 }
94 return 0;
95 }
I LOVE SEGMENT_TREE
[BZOI2014]大融合——————线段树进阶的更多相关文章
- 【BZOJ-4530】大融合 线段树合并
4530: [Bjoi2014]大融合 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 280 Solved: 167[Submit][Status] ...
- BZOJ4919[Lydsy1706月赛]大根堆-------------线段树进阶
是不是每做道线段树进阶都要写个题解..根本不会写 Description 给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点.每个点有一个权值v_i. 你需要将这棵树转化成一个大根堆.确切 ...
- [LOJ#2980][THUSCH2017]大魔法师(线段树+矩阵)
每个线段树维护一个行向量[A,B,C,len]分别是这个区间的A,B,C区间和与区间长度,转移显然. 以及此题卡常,稍微哪里写丑了就能100->45. #include<cstdio> ...
- LOJ 2980 「THUSCH 2017」大魔法师——线段树
题目:https://loj.ac/problem/2980 线段树维护矩阵. 然后是 30 分.似乎是被卡常了?…… #include<cstdio> #include<cstri ...
- [BZOJ3307] 雨天的尾巴-----------------线段树进阶
虽然是个板子,但用到了差分思想. Description N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最 ...
- zhw大神线段树姿势
; i<; i++) tree[i][]=tree[i][]=i; ; i>=; i--) tree[i][]=tree[i+i][], tree[i][]=tree[i+i+][]; v ...
- HDU 5091---Beam Cannon(线段树+扫描线)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5091 Problem Description Recently, the γ galaxies bro ...
- HDU1199 动态线段树 // 离散化
附动态线段树AC代码 http://acm.hdu.edu.cn/showproblem.php?pid=1199 因为昨天做了一道动态线段树的缘故,今天遇到了这题没有限制范围的题就自然而然想到了动态 ...
- [CodeChef - STREETTA] The Street 李超线段树
大致题意: 给出两个序列A,B,A初始为负无穷,B初始为0,有三种操作 1.在A上区间[u,v]上加一个等差数列,取与原本A序列的最大值. 2.在B上区间[u,v]上加一个等差数列. 3.给出一个点X ...
随机推荐
- AQS快速入门
一.模板方法模式 父子类多态,父类中用一个方法调用执行所有所需要的方法: 父类: 子类: 主线程执行时候调用父类的模板方法: 二.AQS思想 sync都是独占锁,lock显示锁也是,只有读写锁是共享锁 ...
- 使用Eclipse对weblogic进行远程调试
一.环境说明 weblogic12c,linux centOS 6.5,eclipse mars. 二.步骤 1.找到weblogic根目录下user_projects/domains/域名/bin/ ...
- python库--tensorflow--RNN(循环神经网络相关)
类/方法 返回值类型 参数 说明 tf.contrib.rnn① / tf.nn.rnn_cell② .RNNCell() 实例r 看不懂 trainable=True name=None d ...
- Lambda函数接口和方法构造器应用
函数式接口 什么是函数式接口? 在java中'有且仅有一个抽象方法的接口',就称为函数式接口. 可以通过Lambda表达式来创建该接口的对象.(若Lambda表达式抛出一个受检异常,那么该异常需要在目 ...
- undefined和null
undefined和null undefined的情景: 声明变量为赋值 var name; console.og(name); //undefined 访问对象上不存在的属性 var obj={} ...
- win8 连接到OneDrive时出现问题-感叹号
显示最后更新时间是1970年... 还有感叹号,没法同步 解决办法: 管理员运行cmd命令: 输入"netsh int ip reset c: esetlog.txt",按下回车键 ...
- win10环境charles抓包unknow问题
win10环境,charles已经安装了证书,但是抓包的时候还是unknow,让人头疼. 1.确保证书安装成功. 2.检查charles设置是否正确. 进入Charles - > Proxy - ...
- android web外壳
参考: 1.https://blog.csdn.net/m0_37201243/article/details/106862817 2.https://www.cnblogs.com/ifaswind ...
- 『GoLang』协程与通道
作为一门 21 世纪的语言,Go 原生支持应用之间的通信(网络,客户端和服务端,分布式计算)和程序的并发.程序可以在不同的处理器和计算机上同时执行不同的代码段.Go 语言为构建并发程序的基本代码块是 ...
- Jupyter lab 配置记录,xpython + R 语言
install.packages(c("repr", "IRdisplay", "evaluate", "crayon" ...