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

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. [CVE-2020-1956] Apache Kylin远程命令执行漏洞复现

    Apache Kylin是一个开源的.分布式的分析型数据仓库,提供Hadoop/Spark之上的 SQL 查询接口及多维分析(OLAP)能力以支持超大规模数据,最初由 eBay 开发并贡献至开源社区. ...

  2. Spring Boot 入门系列(二十七)使用Spring Data JPA 自定义查询如此简单,完全不需要写SQL!

    前面讲了Spring Boot 整合Spring Boot JPA,实现JPA 的增.删.改.查的功能.JPA使用非常简单,只需继承JpaRepository ,无需任何数据访问层和sql语句即可实现 ...

  3. JNDI注入基础

    JNDI注入基础 一.简介 JNDI(The Java Naming and Directory Interface,Java命名和目录接口)是一组在Java应用中访问命名和目录服务的API,命名服务 ...

  4. scrum项目冲刺_day08总结

    摘要:今日完成任务. 1.短信服务正在进行 2.注册登录功能基本实现,但缺少短信验证 3.导航在进行 4.搜索功能基本完成 总任务: 一.appUI页面(已完成) 二.首页功能: 1.图像识别功能(已 ...

  5. nuxt.js同路由跳转参数不同,mounted不执行时

    watch: { '$route'(to, from) { if (to.fullPath !== from.fullPath) { this.$nextTick(() => { // 不加th ...

  6. 重新整理 .net core 周边阅读篇————AspNetCoreRateLimit[一]

    前言 整理了一下.net core 一些常见的库的源码阅读,共32个库,记100余篇. 以下只是个人的源码阅读,如有错误或者思路不正确,望请指点. 正文 github 地址为: https://git ...

  7. Linux系列(12) - find

    简述 find搜索文件,搜索方式丰富,遍历给定范围的所有目录下的文件(避免大范围的搜索,会非常浪费系统资源,建议不在直接在"/"目录下搜索) 命令格式 基本使用 格式:find [ ...

  8. 获取系统版本,判断是windows还是Linux

    package com.foresee.zxpt.common.utils; import java.util.Properties; /** * 获取系统版本 * @author GZ * */ p ...

  9. python学习2-博客-蓝图

    #!/usr/bin/env python # -*- coding: UTF-8 -*- from flask import Blueprint,Flask #这里创建了一个名称为 'admin' ...

  10. 鸿蒙内核源码分析(定时器篇) | 哪个任务的优先级最高 | 百篇博客分析OpenHarmony源码 | v31.02

    百篇博客系列篇.本篇为: v31.xx 鸿蒙内核源码分析(定时器篇) | 哪个任务的优先级最高 | 51.c.h .o 本篇说清楚定时器的实现 读本篇之前建议先读鸿蒙内核源码分析(总目录)其余篇. 运 ...