[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 ...
随机推荐
- k8s标签label
1.给节点设置标签 一遍pod部署选择 kubectl label node 节点名 disktype=ssd kubectl label node master1 disktype=ssd 效果 [ ...
- Dockerfile自动制作Docker镜像(二)—— 其它常用命令
Dockerfile自动制作Docker镜像(二)-- 其它常用命令 前言 a. 本文主要为 Docker的视频教程 笔记. b. 环境为 CentOS 7.0 云服务器 c. 上一篇:Dockerf ...
- 使用git克隆仓库到本地报错:SSL certificate problem: unable to get local issuer certificate
第一次使用Git工具克隆仓库,使用的是HTTPS链接,失败了.发现是因为通过HTTPS访问时,如果服务器上的SSL证书未经过第三方机构认证,Git就会报错. 解决方法:通过命令关闭验证 git con ...
- HCNP Routing&Switching之路由过滤工具Filter-Policy
前文我们了解了路由控制技术中路由策略和路由匹配工具IP-Prefix相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15314262.html:今天我们 ...
- html 表单input disabled属性提交后台无法获得数据
在input上加入disabled属性后, 点击提交会遗漏该值, 有两个办法: 一 可以考虑readonly属性,一样的不可修改操作,但是可以提交 二 在提交时 js 代码操作去除input上的dis ...
- 小学生都能读懂的网络协议之:WebSocket
目录 简介 webSocket vs HTTP HTTP upgrade header websocket的优点 webScoket的应用 websocket的握手流程 WebSocket API 总 ...
- Jmeter系列(6)- 分析源码,创建登录、浏览商品接口请求
前言简介 接口的压力测试有个二八原则:线上80%的用户量在一天24小时20%(即4.8个小时)的时间里可以平稳运行,这个接口就算是通过压力测试了 源码分析 登录 浏览商品 创建请求 登录 浏览菜单 C ...
- linux系统运维操作规范
1.1安装流程 1.1.1 系统如无特殊要求一律采用小化安装方式进行安装. 1.1.2 安装过程开始之前需要根据实际情况进行CPU数量.磁盘容量.内存分配.文件系统.目录结构.磁盘分区规划.磁盘管理方 ...
- disruptor笔记之四:事件消费知识点小结
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- P4245-[模板]任意模数多项式乘法
正题 题目链接:https://www.luogu.com.cn/problem/P4245 题目大意 两个多项式,求它们的乘积模\(p\). 解题思路 方法好像挺多,我用的是最简单的一种就是,先定一 ...