[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 ...
随机推荐
- [CVE-2020-1956] Apache Kylin远程命令执行漏洞复现
Apache Kylin是一个开源的.分布式的分析型数据仓库,提供Hadoop/Spark之上的 SQL 查询接口及多维分析(OLAP)能力以支持超大规模数据,最初由 eBay 开发并贡献至开源社区. ...
- Spring Boot 入门系列(二十七)使用Spring Data JPA 自定义查询如此简单,完全不需要写SQL!
前面讲了Spring Boot 整合Spring Boot JPA,实现JPA 的增.删.改.查的功能.JPA使用非常简单,只需继承JpaRepository ,无需任何数据访问层和sql语句即可实现 ...
- JNDI注入基础
JNDI注入基础 一.简介 JNDI(The Java Naming and Directory Interface,Java命名和目录接口)是一组在Java应用中访问命名和目录服务的API,命名服务 ...
- scrum项目冲刺_day08总结
摘要:今日完成任务. 1.短信服务正在进行 2.注册登录功能基本实现,但缺少短信验证 3.导航在进行 4.搜索功能基本完成 总任务: 一.appUI页面(已完成) 二.首页功能: 1.图像识别功能(已 ...
- nuxt.js同路由跳转参数不同,mounted不执行时
watch: { '$route'(to, from) { if (to.fullPath !== from.fullPath) { this.$nextTick(() => { // 不加th ...
- 重新整理 .net core 周边阅读篇————AspNetCoreRateLimit[一]
前言 整理了一下.net core 一些常见的库的源码阅读,共32个库,记100余篇. 以下只是个人的源码阅读,如有错误或者思路不正确,望请指点. 正文 github 地址为: https://git ...
- Linux系列(12) - find
简述 find搜索文件,搜索方式丰富,遍历给定范围的所有目录下的文件(避免大范围的搜索,会非常浪费系统资源,建议不在直接在"/"目录下搜索) 命令格式 基本使用 格式:find [ ...
- 获取系统版本,判断是windows还是Linux
package com.foresee.zxpt.common.utils; import java.util.Properties; /** * 获取系统版本 * @author GZ * */ p ...
- python学习2-博客-蓝图
#!/usr/bin/env python # -*- coding: UTF-8 -*- from flask import Blueprint,Flask #这里创建了一个名称为 'admin' ...
- 鸿蒙内核源码分析(定时器篇) | 哪个任务的优先级最高 | 百篇博客分析OpenHarmony源码 | v31.02
百篇博客系列篇.本篇为: v31.xx 鸿蒙内核源码分析(定时器篇) | 哪个任务的优先级最高 | 51.c.h .o 本篇说清楚定时器的实现 读本篇之前建议先读鸿蒙内核源码分析(总目录)其余篇. 运 ...