题目

题意

road命令连接第A坐标和第B坐标的点。而line则是查看纵坐标C拉出的扫描线过几个联通块,要求求联通块中的数量和是多少。(具体的可以查看原题)

题解

其实是线段树一个简单的模拟,即并查集找联通块和联通块中点的数量,然后每次更新的时候,删除A点和B点的信息,重新建立A点和B点连接后的信息就行了。

#include<iostream>
#include<cstring>
#include<sstream>
#include<string>
#include<cstdio>
#include<cctype>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<list>
#include<set>
#include<map>
#include<algorithm>
#define fi first
#define se second
#define MP make_pair
#define P pair<int,int>
#define PLL pair<ll,ll>
#define Sca(x) scanf("%d",&x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x)
#define Scl2(x,y) scanf("%lld%lld",&x,&y)
#define Scl3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z)
#define Pri(x) printf("%d\n",x)
#define Prl(x) printf("%lld\n",x)
#define For(i,x,y) for(int i=x;i<=y;i++)
#define _For(i,x,y) for(int i=x;i>=y;i--)
#define FAST_IO std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define ll long long
const int INF=0x3f3f3f3f;
const ll INFL=0x3f3f3f3f3f3f3f3f;
const double Pi = acos(-1.0);
using namespace std;
template <class T>void tomax(T&a,T b){ a=max(a,b); }
template <class T>void tomin(T&a,T b){ a=min(a,b); }
const int N=1e5+5;
struct Segt{#define lc (p<<1)#define rc (p<<1|1)#define MID (tree[p].l+tree[p].r)>>1struct Tree{int l,r;int uck,val,lz[2];inline void init(int left,int right){ l=left; r=right; uck=0; val=0; lz[0]=0; lz[1]=0; }void updata(int uckv,int valv){ uck+=uckv; val+=valv; lz[0]+=uckv; lz[1]+=valv; }}tree[N<<2|1];void pushdown(int p){  tree[p].uck=tree[lc].uck+tree[rc].uck;  tree[p].val=tree[lc].val+tree[rc].val; }void pushup(int p){int one=tree[p].lz[0],two=tree[p].lz[1];tree[lc].updata(one,two);tree[rc].updata(one,two);tree[p].lz[0]=0; tree[p].lz[1]=0;}void build(int l,int r,int p){tree[p]=Tree{l,r,0,0,0,0};if(l==r) return ;int mid=MID;build(l,mid,lc);build(mid+1,r,rc);}void updata(int l,int r,int p,int uckv,int valv){if(l>r) return ;if(tree[p].l>=l&&tree[p].r<=r){ tree[p].updata(uckv,valv); return ; }if(tree[p].lz[0] || tree[p].lz[1]) pushup(p);int mid=MID;if(l<=mid) updata(l,r,lc,uckv,valv);if(r>mid) updata(l,r,rc,uckv,valv);pushdown(p);}P getans(int pos,int p){if(tree[p].l==pos && tree[p].r==pos) return MP(tree[p].uck,tree[p].val);if(tree[p].lz[0] || tree[p].lz[1]) pushup(p);int mid=MID;if(pos<=mid) return getans(pos, lc);if(pos>mid) return getans(pos, rc);}
}t;
struct Up{ int minn,maxx; } up[N];
int num[N],tmp[N],uck[N],ans[N];
int len=0;
int find(int x){ return uck[x]==x ? x : uck[x]=find(uck[x]); }
void merge(int x,int y){int t1(find(x)),t2(find(y));if(t1!=t2){t.updata(up[t1].minn+1,up[t1].maxx,1,-1,-ans[t1]);t.updata(up[t2].minn+1,up[t2].maxx,1,-1,-ans[t2]);uck[t2]=t1;ans[t1]+=ans[t2];tomax(up[t1].maxx,up[t2].maxx); tomin(up[t1].minn,up[t2].minn);t.updata(up[t1].minn+1,up[t1].maxx,1,1,ans[t1]);}
}
inline void dis(int n){sort(tmp+1,tmp+1+n);len=unique(tmp+1,tmp+1+n) - tmp - 1;For(i,1,n) num[i]=lower_bound(tmp+1,tmp+1+len,num[i]) - tmp;
}
inline void init(int n){dis(n);For(i,1,n){ uck[i]=i; ans[i]=1; up[i]=Up{num[i], num[i]}; }
}
int main(){int T; Sca(T);while(T--){int n; Sca(n);For(i,1,n){ int x; Sca(x); Sca(num[i]); tmp[i]=num[i]; }init(n);t.build(1,len,1);int m; Sca(m);while(m--){char cmd[10]; scanf("%s",cmd);if(cmd[0]=='r'){ int x,y; Sca2(x,y); x++; y++; merge(x,y); }else if(cmd[0]=='l'){double x; scanf("%lf",&x);x+=0.5;x = lower_bound(tmp+1,tmp+1+len,x) - tmp;if(x==len+1) puts("0 0");else{P out = t.getans(x,1);printf("%d %d\n",out.fi,out.se);}}}}
}

UVA11992(线段树)相关推荐

  1. UVA11992不错的线段树段更新

    题意:       给你一个矩阵,最大20*50000的,然后有三个操作 1 x1 y1 x2 y2 v  把子矩阵的值全部都加上v 2 x1 y1 x2 y2 v  把子矩阵的值全部都变成v 2 x ...

  2. 二逼平衡树——树套树(线段树套Splay平衡树)

    题面 Bzoj3196 解析 线段树和Splay两棵树套在一起,常数直逼inf,但最终侥幸过了 思路还是比较简单, 在原数组维护一个下标线段树,再在每一个线段树节点,维护一个对应区间的权值Splay. ...

  3. 线段树——HDU - 1698

    题目含义 就是初始化一堆数为1 可以经过操作把一个区间的数都改变 并求这堆数的总大小 题目分析 有一个 #include<iostream> #include<stdio.h> ...

  4. BZOJ.1558.[JSOI2009]等差数列(线段树 差分)

    BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...

  5. 【线段树分治 线性基】luoguP3733 [HAOI2017]八纵八横

    不知道为什么bzoj没有HAOI2017 题目描述 Anihc国有n个城市,这n个城市从1~n编号,1号城市为首都.城市间初始时有m条高速公路,每条高速公路都有一个非负整数的经济影响因子,每条高速公路 ...

  6. [bzoj1582][Usaco2009 Hol]Holiday Painting 节日画画_线段树

    Holiday Painting 节日画画 bzoj-1582 Usaco-2009 Hol 题目大意:给定两个n*m的01网格图.q次操作,每次将第二个网格图的子矩阵全部变成0或1,问每一次操作后两 ...

  7. codefores 786B. Legacy(最短路,线段树优化拆点,好题)

    题目链接 B. Legacy time limit per test2 seconds memory limit per test256 megabytes inputstandard input o ...

  8. 【题解】BZOJ 3065: 带插入区间K小值——替罪羊树套线段树

    题目传送门 题解 orz vfk的题解 3065: 带插入区间K小值 系列题解 一 二 三 四 惨 一开始用了一种空间常数很大的方法,每次重构的时候merge两颗线段树,然后无限RE(其实是MLE). ...

  9. 树链剖分+线段树 HDOJ 4897 Little Devil I(小恶魔)

    题目链接 题意: 给定一棵树,每条边有黑白两种颜色,初始都是白色,现在有三种操作: 1 u v:u到v路径(最短)上的边都取成相反的颜色 2 u v:u到v路径上相邻的边都取成相反的颜色(相邻即仅有一 ...

最新文章

  1. 中国科学家研发新的全基因组组装算法
  2. HDU 2066-一个人的旅行(最短路Dijkstra)
  3. 政府网站公祭日,如何使网站整体变灰
  4. lazyload.js详解
  5. 【问链财经-区块链基础知识系列】 第二十八课 区块链如何助力万亿规模的供应链金融蛋糕
  6. 将表达式转换成逆波兰式
  7. File类获取功能的方法
  8. substr(IndexAction,1,-6)
  9. 使用Visual Studio Code 开发.NET Core应用程序
  10. 11 为了进一步_浅聊小米11发布会
  11. oracle 表空间 碎片,Oracle表空间碎片整理
  12. pytorch实战从入门到精通第三部分——数据处理
  13. windows多线程详解
  14. SQL Server中使用索引性能的比较
  15. 数据库实验1---创建数据库和表
  16. EXCEL密码清除(破解找回密码)——巧用宏代码
  17. C语言练习之打印9*9乘法口诀表
  18. 心形一行python_心的解释|心的意思|汉典“心”字的基本解释
  19. intellij IDEA更换主题为Darcula后中文项目名称变口(方框)的解决办法
  20. SpringBoot 自动配置初探

热门文章

  1. poj3179 : corral the cows-离散化的巧妙运用
  2. 功率单位dBm及其换算
  3. Nodejs影院售票管理系统的设计和实现(含论文)
  4. Java中夏令时问题
  5. python中delay__Python time delay
  6. 【stm32】delay详解
  7. 上海大厂Android面试经历:史上最通俗计算机网络分层详解,通用流行框架大全
  8. 2020前端开发者的面试(2),不定时更新
  9. caffe与cv2图片格式的相互转换
  10. 职工信息存入文件employee,再抽取部分信息存入另一个文件employee_type