当数据过多时,往往我们的内存不够用了,但是呢,我们发现很多时候我们可以将这些区间压缩。例如,这道离散化的板子题~
这道题是Corrupt Mayor’s Performance Art的升级版。题意都差不多,让你求区间的颜色数量。有区别的就是,这道题的数据相当大!1E9
所以,这道题的精髓在于:将每个区间离散化处理了,关于离散化的说明这里有详细的讲解
注意,离散化时,最好用map,我一开始开了两个数组,直接把一个数组的值当作另一个数组的序号…结果嘛
…最后去问了学长,才知道要用map…感谢某嘤嘤怪 学长喵~
AC代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define ll long long
#define lowbit(x) (x&(-x))
#define MT(a,b) memset(a,b,sizeof(a))
const int maxn=2E5+5;
const int ONF=-0x3f3f3f3f;
const int INF=0x3f3f3f3f;
int ans;
bool vis[maxn];
int rilegou[maxn<<2];
//int buyaorigou[maxn<<2];
map<int,int>jiushiyaorigou;
pair<int,int>p[maxn];
struct node
{
int val,lazy;
}qwe[maxn<<2];
void update(int root)
{
if (qwe[root<<1].val==qwe[root<<1|1].val){
qwe[root].val=qwe[root<<1].val;
} else qwe[root].val=0;
}
void build_tree(int l,int r,int root)
{
qwe[root].lazy=0;
if (l==r){
qwe[root].val=-1;
return;
}
int mid=(l+r)>>1;
build_tree(l,mid,root<<1);
build_tree(mid+1,r,root<<1|1);
update(root);
}
void pushdown(int root)
{
if (qwe[root].lazy==0) return;
qwe[root<<1].lazy=qwe[root<<1].val=qwe[root].lazy;
qwe[root<<1|1].lazy=qwe[root<<1|1].val=qwe[root].lazy;
qwe[root].lazy=0;
}
void add (int l,int r,int ql,int qr,int root,int val)
{
if (l==ql&&r==qr){
qwe[root].lazy=qwe[root].val=val;
return;
}
pushdown(root);
int mid=(l+r)>>1;
if (qr<=mid) add(l,mid,ql,qr,root<<1,val);
else if (ql>mid) add(mid+1,r,ql,qr,root<<1|1,val);
else{
add(l,mid,ql,mid,root<<1,val);
add(mid+1,r,mid+1,qr,root<<1|1,val);
}
update(root);
}
void getans(int root){
if (qwe[root].val==-1) return;
if (qwe[root].val!=0){
if (vis[qwe[root].val]==false){
ans++;
vis[qwe[root].val]=true;
}
return;
}
getans(root<<1);
getans(root<<1|1);
}
int main ()
{
int cnt,t,n;
scanf ("%d",&t);while (t--){
cnt=0;
MT(vis, false);
scanf ("%d",&n);
for (int i=1;i<=n;i++){
scanf ("%d%d",&p[i].first,&p[i].second);
rilegou[++cnt]=p[i].first;
rilegou[++cnt]=p[i].second;
}
sort(rilegou+1,rilegou+1+2*n);
cnt=unique(rilegou+1,rilegou+1+2*n)-(rilegou+1);
for (int i=1;i<=cnt;i++){
// buyaorigou[rilegou[i]]=i;
jiushiyaorigou[rilegou[i]]=i;
}
build_tree(1,cnt,1);
for (int i=1;i<=n;i++){
add(1,cnt,jiushiyaorigou[p[i].first],jiushiyaorigou[p[i].second],1,i);
}
ans=0;getans(1);
printf("%d\n",ans);
}
return 0;
}
我注释掉的就是我第一次用两个数组的时候的代码。