竟然改了不到一小时就改出来了, 可喜可贺

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]大融合——————线段树进阶的更多相关文章

  1. 【BZOJ-4530】大融合 线段树合并

    4530: [Bjoi2014]大融合 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 280  Solved: 167[Submit][Status] ...

  2. BZOJ4919[Lydsy1706月赛]大根堆-------------线段树进阶

    是不是每做道线段树进阶都要写个题解..根本不会写 Description 给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点.每个点有一个权值v_i. 你需要将这棵树转化成一个大根堆.确切 ...

  3. [LOJ#2980][THUSCH2017]大魔法师(线段树+矩阵)

    每个线段树维护一个行向量[A,B,C,len]分别是这个区间的A,B,C区间和与区间长度,转移显然. 以及此题卡常,稍微哪里写丑了就能100->45. #include<cstdio> ...

  4. LOJ 2980 「THUSCH 2017」大魔法师——线段树

    题目:https://loj.ac/problem/2980 线段树维护矩阵. 然后是 30 分.似乎是被卡常了?…… #include<cstdio> #include<cstri ...

  5. [BZOJ3307] 雨天的尾巴-----------------线段树进阶

    虽然是个板子,但用到了差分思想. Description N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最 ...

  6. zhw大神线段树姿势

    ; i<; i++) tree[i][]=tree[i][]=i; ; i>=; i--) tree[i][]=tree[i+i][], tree[i][]=tree[i+i+][]; v ...

  7. HDU 5091---Beam Cannon(线段树+扫描线)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5091 Problem Description Recently, the γ galaxies bro ...

  8. HDU1199 动态线段树 // 离散化

    附动态线段树AC代码 http://acm.hdu.edu.cn/showproblem.php?pid=1199 因为昨天做了一道动态线段树的缘故,今天遇到了这题没有限制范围的题就自然而然想到了动态 ...

  9. [CodeChef - STREETTA] The Street 李超线段树

    大致题意: 给出两个序列A,B,A初始为负无穷,B初始为0,有三种操作 1.在A上区间[u,v]上加一个等差数列,取与原本A序列的最大值. 2.在B上区间[u,v]上加一个等差数列. 3.给出一个点X ...

随机推荐

  1. JS006. 详解自执行函数原理与数据类型的快速转换 (声明语句、表达式、运算符剖析)

    今天的主角: Operator Description 一元正值符 " + "(MDN) 一元运算符, 如果操作数在之前不是number,试图将其转换为number. 圆括号运算符 ...

  2. Object类、Date类、Calendar类、System类、StringBuilder类和基本类型包装类

    一.Object类--toString方法 1.普通类重写toString方法,不然打印出来是存在栈内存的对象引用名称的堆内存中该对象的地址值: 2.equals方法: String比较equals是 ...

  3. 常见shell脚本测试题 for/while语句

    1.计算从1到100所有整数的和2.提示用户输入一个小于100的整数,并计算从1到该数之间所有整数的和3.求从1到100所有整数的偶数和.奇数和4.执行脚本输入用户名,若该用户存在,输出提示该用户已存 ...

  4. 密码学系列之:bcrypt加密算法详解

    目录 简介 bcrypt的工作原理 bcrypt算法实现 bcrypt hash的结构 hash的历史 简介 今天要给大家介绍的一种加密算法叫做bcrypt, bcrypt是由Niels Provos ...

  5. tcpdump使用手册

    tcp使用手册 格式: tcpdump [选项] [过滤条件] 选项: -i eth0 #网卡接口 -A #以ASCII码格式阅读 -w file #下载抓取的数据包 -r file #上传数据包 - ...

  6. windows中对文件进行排序

    右键->排序方式->更多->选择需要的项目

  7. WebView(网页视图)基本用法

    资料来源于菜鸟教程 啊这官方文档居然失效了,打不开.那我们直接就看相关方法: WebChromeClient:辅助WebView处理Javascript的对话框.网站图标.网站title.加载进度等! ...

  8. ECMAScript 2021(ES12)新特性简介

    简介 ES12是ECMA协会在2021年6月发行的一个版本,因为是ECMAScript的第十二个版本,所以也称为ES12. ES12发行到现在已经有一个月了,那么ES12有些什么新特性和不一样的地方呢 ...

  9. 这个 MySQL bug 让我大开眼界

    这周收到一个 sentry 报警,如下 SQL 查询超时了. select * from order_info where uid = 5837661 order by id asc limit 1 ...

  10. 使用正则表达式在VS中批量移除 try-catch

    使用正则表达式在VS中批量移除 try-catch 前言 try-catch 意为捕获错误,一般在可能出错的地方使用(如调用外部函数或外部设备),以对错误进行正确的处理,并进行后续操作而不至于程序直接 ...