Mayor's posters(离散化优化喵与线段树喵~)

当数据过多时,往往我们的内存不够用了,但是呢,我们发现很多时候我们可以将这些区间压缩。例如,这道离散化的板子题~
这道题是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;
}

我注释掉的就是我第一次用两个数组的时候的代码。

发布了33 篇原创文章 · 获赞 15 · 访问量 914

猜你喜欢

转载自blog.csdn.net/weixin_43925900/article/details/97496837
今日推荐