poj2528 Mayor's posters (离散化+线段树,区间修改,单点查询)

对整个区间进行标记,查询时进行单点查询,最后统计出现了多少种。

#include<iostream>
#include<cstring>
#include<set>
#include<algorithm>
using namespace std;
const int maxn = 1e5+5;
typedef long long ll;
int num[2*maxn],info[4*maxn];
struct Line
{
    int l,r;
}line[maxn];

int t;
void pushDown(int i)
{
    if(info[i])    
    {
        info[i*2] = info[i];
        info[i*2+1] = info[i];
        info[i] = 0;
    }
}

int query(int x,int i, int l,int r)
{
    if(l == r)  return info[i];
    pushDown(i);

    int m = (l + r) / 2;
    if(x <= m)
        return query(x,i*2,l,m);
    else
        return query(x,i*2+1,m+1,r);
}

void Update(int id,int val,int ql,int qr,int l,int r)
{
  //  if(ql > r || qr < l)    return;
    if(l >= ql && qr >= r)
    {
        info[id] = val;
        return;
    }
    pushDown(id);

    int mid = (l + r) / 2;
    if(ql <= mid) Update(id*2,val,ql,qr,l,mid);
    if(mid<qr) Update(id*2+1,val,ql,qr,mid + 1,r);
}

set<int> ans;//这里进行了修改
void solve()
{
    ans.clear();
    for(int i = 1;i <= t;++i)
   {
        int temp = query(i,1,1,t);
        if(temp >= 1 && temp <= t)  ans.insert(temp);
    }
    cout<<ans.size()<<endl;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);cout.tie(NULL);
    int n,T,cnt;

    cin>>T;
    while(T--)
    {
        memset(info,0,sizeof(info));
        cnt = 0;
        cin>>n;
        for(int i = 1;i <= n;++i)
        {
            int a,b;
            cin >> a >> b;
            num[++cnt] = a;
            num[++cnt] = b;
            line[i].l = a,line[i].r = b; 
        }

        sort(num+1,num+cnt+1);
        int size = unique(num+1,num+cnt+1) - num - 1;
        t = size;
        for(int i = 2;i <= size;++i)
            if(num[i] - num[i - 1] > 1) num[++t] = num[i - 1] + 1;
        sort(num+1,num+t+1);

        int x,y;
        for(int i=1;i<=n;i++)
        {
            x=lower_bound(num+1,num+t+1,line[i].l)-num;
            y=lower_bound(num+1,num+t+1,line[i].r)-num;
            Update(1,i,x,y,1,t);
        }

        solve();
    }

    return 0;
}

参考博客:https://blog.csdn.net/mmy1996/article/details/60884022

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值