线段树区间更新,区间统计+离散化 POJ 2528 Mayor's posters
题意:有一个非常长的板子(10000000长),在上面贴n(n<=10000)张海报。问最后从外面能看到几张不同的海报。
由于板子有10000000长,直接建树肯定会爆,所以须要离散化处理,对于每张海报,有两个端点值,最后能看到几张海报跟他们的端点值的相对大小有关,跟绝对大小无关。所以就把全部海报的端点离散化处理,总共2n个端点,排序去重,相应p(p<=2n)个点。
然后建树,由于p不超过20000,所以这样就能够接受了。区间更新时,由于我们仅仅关心最外面海报的颜色有多少种。所以向下传递节点信息的时候把上面节点的信息去掉。这样在查询的时候就能方便一些,用一个标记数组记录总共同拥有多少种颜色就能够了。
代码:
- #include <cstdlib>
- #include <cctype>
- #include <cstring>
- #include <cstdio>
- #include <cmath>
- #include<climits>
- #include <algorithm>
- #include <vector>
- #include <string>
- #include <iostream>
- #include <sstream>
- #include <map>
- #include <set>
- #include <queue>
- #include <stack>
- #include <fstream>
- #include <numeric>
- #include <iomanip>
- #include <bitset>
- #include <list>
- #include <stdexcept>
- #include <functional>
- #include <utility>
- #include <ctime>
- using namespace std;
- #define PB push_back
- #define MP make_pair
- #define REP(i,x,n) for(int i=x;i<(n);++i)
- #define FOR(i,l,h) for(int i=(l);i<=(h);++i)
- #define FORD(i,h,l) for(int i=(h);i>=(l);--i)
- #define SZ(X) ((int)(X).size())
- #define ALL(X) (X).begin(), (X).end()
- #define RI(X) scanf("%d", &(X))
- #define RII(X, Y) scanf("%d%d", &(X), &(Y))
- #define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
- #define DRI(X) int (X); scanf("%d", &X)
- #define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
- #define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
- #define OI(X) printf("%d",X);
- #define RS(X) scanf("%s", (X))
- #define MS0(X) memset((X), 0, sizeof((X)))
- #define MS1(X) memset((X), -1, sizeof((X)))
- #define LEN(X) strlen(X)
- #define F first
- #define S second
- #define Swap(a, b) (a ^= b, b ^= a, a ^= b)
- #define Dpoint strcut node{int x,y}
- #define cmpd int cmp(const int &a,const int &b){return a>b;}
- /*#ifdef HOME
- freopen("in.txt","r",stdin);
- #endif*/
- const int MOD = 1e9+7;
- typedef vector<int> VI;
- typedef vector<string> VS;
- typedef vector<double> VD;
- typedef long long LL;
- typedef pair<int,int> PII;
- //#define HOME
- int Scan()
- {
- int res = 0, ch, flag = 0;
- if((ch = getchar()) == '-') //推断正负
- flag = 1;
- else if(ch >= '0' && ch <= '9') //得到完整的数
- res = ch - '0';
- while((ch = getchar()) >= '0' && ch <= '9' )
- res = res * 10 + ch - '0';
- return flag ? -res : res;
- }
- /*----------------PLEASE-----DO-----NOT-----HACK-----ME--------------------*/
- int data[100000+10];
- int n;
- int a[20010];
- int b[20010];
- int u[40000];
- void pushdown(int rt)
- {
- if(data[rt]!=-1)
- {
- data[rt<<1]=data[(rt<<1)+1]=data[rt];
- data[rt]=-1;
- }
- }
- void build(int l,int r,int rt)
- {
- if(l==r)
- {
- data[rt]=-1;
- return;
- }
- int m=(l+r)>>1;
- build(l,m,rt<<1);
- build(m+1,r,(rt<<1)+1);
- }
- void update(int l,int r,int rt,int a,int b,int c)
- {
- if(a<=l&&r<=b)
- {
- data[rt]=c;
- return;
- }
- pushdown(rt);
- int m=(l+r)>>1;
- if(a<=m)
- update(l,m,rt<<1,a,b,c);
- if(b>m)
- update(m+1,r,(rt<<1)+1,a,b,c);
- }
- int vis[20010];
- int sum;
- void query(int l,int r,int rt)
- {if(data[rt]!=-1)
- {
- if(!vis[data[rt]])
- {
- vis[data[rt]]=1;
- sum++;
- }
- return;
- }
- int m=(l+r)>>1;
- query(l,m,rt<<1);
- query(m+1,r,(rt<<1)+1);
- }
- int main()
- {
- int c;
- RI(c);
- while(c--)
- {RI(n);
- REP(i,0,n)
- {
- RII(a[i],b[i]);
- }
- REP(i,0,n)
- {
- u[i]=a[i];
- u[i+n]=b[i];
- }
- sort(u,u+2*n);
- int p=unique(u,u+2*n)-u;
- REP(i,0,n)
- {int t=lower_bound(u,u+p,a[i])-u;
- a[i]=t+1;
- t=lower_bound(u,u+p,b[i])-u;
- b[i]=t+1;
- }
- build(1,p,1);
- REP(i,0,n)
- {
- update(1,p,1,a[i],b[i],i);
- }
- MS0(vis);
- sum=0;
- query(1,p,1);
- printf("%d\n",sum);
- }
- return 0;
- }
线段树区间更新,区间统计+离散化 POJ 2528 Mayor's posters的更多相关文章
- POJ 2528 Mayor's posters 离散化+线段树
题目大意:给出一些海报和贴在墙上的区间.问这些海报依照顺序贴完之后,最后能后看到多少种海报. 思路:区间的范围太大,然而最多仅仅会有10000张海报,所以要离散化. 之后用线段树随便搞搞就能过. 关键 ...
- POJ 2528 Mayor's posters 离散化和线段树题解
本题就是要往墙上贴海报,问最后有多少可见的海报. 事实上本题的难点并非线段树,而是离散化. 由于数据非常大,直接按原始数据计算那么就会爆内存和时间的. 故此须要把数据离散化. 比方有海报1 6 7 ...
- poj 2528 Mayor's posters
这个题意是市长竞选,然后每一个人都能够贴广告牌.能够覆盖别人的看最后剩几个广告牌 这题目想了两个多小时,最后忍不住看了一下题解. 发现仅仅是简单地hash 和线段树成段更新 由于有10000个人竞选 ...
- poj 2528 Mayor's posters 【线段树 + 离散化】
Mayor's posters Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 50643 Accepted: 14675 ...
- POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化)
POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化) 题意分析 前置技能 线段树求逆序对 离散化 线段树求逆序对已经说过了,具体方法请看这里 离散化 有些数 ...
- POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)
POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...
- HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)
HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...
- hdu 1166线段树 单点更新 区间求和
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- hdu2795(线段树单点更新&区间最值)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795 题意:有一个 h * w 的板子,要在上面贴 n 条 1 * x 的广告,在贴第 i 条广告时要 ...
随机推荐
- 零基础学Python不迷茫——基本学习路线及教程!
什么是Python? 在过去的2018年里,Python成功的证明了它自己有多火,它那“简洁”与明了的语言成功的吸引了大批程序员与大数据应用这的注意,的确,它的实用性的确是配的上它的热度. Pyt ...
- 组队赛Day1第一场 GYM 101350 F. Monkeying Around(线段树)
[题目大意] 有n只猴子坐在树上,m个笑话. 给出每个讲这个笑话的猴子的编号,笑话的编号,和笑话的影响半径. 如果一个树上的猴子听了没听过的笑话,会掉到树下.如果听过并且在树下,就会爬到树上. 问最后 ...
- Uiautomator简介及其环境搭建、测试执行
UiAutomator框架使用指南 UiAutomator是Google开发的自动化测试工具,通过UI创建自动化测试代码,来测试界面(UI)的有效功能,可以针对应用程序运行在一个或更多的设备上.我们并 ...
- ubuntu下svn在挂在的NTFS分区上无法报错,提示没有权限
终极解决方案: 赋予svn文件root权限 1. 查找svn文件: $ whereis svn svn: /usr/bin/svn /usr/bin/X11/svn /usr/share/.gz $ ...
- Docker存储和网络
Docker存储资源类型 docker两种存储资源类型 用户在使用 Docker 的过程中,势必需要查看容器内应用产生的数据,或者需要将容器内数据进行备份,甚至多个容器之间进行数据共享,这必然会涉及到 ...
- 1. Go的安装和第一行代码
Go 语言环境安装 Go 语言支持以下系统: Linux FreeBSD Mac OS X(也称为 Darwin) Windows 安装包下载地址为:https://golang.org/dl/. 如 ...
- Wp8 读取手机信息
/// <summary> /// 获取系统信息 /// </summary> private void GetSystemInfo() { lblMsg.Text = str ...
- Python常用操作符
Python常用操作符 1.成员关系操作符in 显示的数字前面填充'0'代替空格 6.转义字符 符号 含义 \' 单引号\" 双引号\a 发出系统响铃声\b 退格符\n 换行符\t 横向制表 ...
- 算法复习——欧拉回路混合图(bzoj2095二分+网络流)
题目: Description YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个小岛之间不会有两座桥,并且从一个小岛可以到另外任意一个小岛.现在YYD想骑单车 ...
- 算法复习——单调队列(sliding windows,ssoi)
题目: 题目描述 给你一个长度为 N 的数组,一个长为 K 的滑动的窗体从最左移至最右端,你只能见到窗口的 K 个整数,每次窗体向右移动一位,如下表: