poj2528 解题报告

这份代码由于color最大值会>10000,而1<<color肯定会炸的

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <map>
using namespace std;
#define ll long long
const int maxn=2e5+10;
const int MAX=1e7+10;
typedef pair<int ,int> p;
p node[maxn];
map<int,int> mp;
struct tree
{
    int left,right;
    int val;
    int add;
}tree[maxn<<2];
int a[MAX];
void pushUp(int root)
{
    //用二进制记录颜色
    tree[root].val=tree[root<<1].val|tree[root<<1|1].val;
}
void pushDown(int root)
{
    tree[root<<1].add=tree[root].add;
    tree[root<<1|1].add=tree[root].add;
    tree[root<<1].val=1<<tree[root].add;
    tree[root<<1|1].val=1<<tree[root].add;
    tree[root].add=0;
}
void build(int l ,int r,int root)
{
    tree[root].left=l;
    tree[root].right=r;
    tree[root].val=0;
    tree[root].add=0;
    if(l==r)
        return ;
    int mid=l+r>>1;
    build(l,mid ,root<<1);
    build(mid+1,r,root<<1|1);
    pushUp(root);

}
void upDate(int l,int r,int root,int color)
{
    if(tree[root].left>=l&&tree[root].right<=r)
    {
        tree[root].add=color;
        tree[root].val=(1<<color);
        return;
    }
    if(tree[root].add ) pushDown(root);
    int mid=tree[root].left+tree[root].right>>1;
    if(l<=mid) upDate(l,r,root<<1,color);
    if(r>mid) upDate(l,r,root<<1|1,color);
    pushUp(root);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        int cnt=0;
        int mxn=0;
        memset(a,0,sizeof(a));
        for(int i=1;i<=n;i++)
        {
            int x, y;
            scanf("%d%d",&x,&y);
            a[x]=1;
            a[y]=1;
            mxn=mxn<x?x:mxn;
            mxn=mxn<y?y:mxn;
            node[i].first=x;node[i].second=y;
        }
        int ans=1;

        for(int i=1;i<=mxn;i++)
        {
            if( a[i] ) mp[i] = ans++;
        }
        build(1,ans-1,1);
        for(int i=1;i<=n;i++)
        {
            int l=mp[node[i].first];
            int r=mp[ node[i].second];
            upDate(l,r,1,i);
        }
        //处理tree[1].val
        int wc=tree[1].val;
        //cout<<wc<<"---"<<endl;
        int ass=0;
        while(wc>0)
        {
            ass+=wc%2;
            wc=wc/2;
        }
        printf("%d\n",ass);
    }


    return 0;
}

另加别人代码:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <map>
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
using namespace std;
#define ll long long
const int maxn=11111;
int col[maxn<<3],li[maxn],ri[maxn],x[maxn<<1],ans;
bool hash[maxn];
void pushDown(int root)
{
    if(col[root]!=-1)
    {
        col[root<<1]=col[root<<1|1]=col[root];
        col[root]=-1;
    }
}
void upDate(int LL,int RR,int c,int l,int r,int root)
{  //c是颜色
    if(LL<=l&&r<=RR)
    {
        col[root]=c;
        return;
    }
    pushDown(root);
    int mid=l+r>>1;
    if(LL<=mid) upDate(LL,RR,c,lson);
    if(RR>mid) upDate(LL,RR,c,rson);
}
void query(int l,int r,int root)
{
    if(col[root]!=-1)
    {
        if( !hash[col[root]] ) ans++;
        hash[col[root]]=true;
        return;
    }
    if(l==r) return ;
    int mid=l+r>>1;
    query(lson);
    query(rson);
}
int Bin(int key,int len)
{
    int l=0,r=len-1;
    while(l<=r)
    {
        int m=(l+r)>>1;
        if(x[m]==key) return m;
        else if(x[m]>key) r=m-1;
        else l=m+1;
    }
    return -1;
}

int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        int nn=0;
        for(int i=0;i<n;i++)
        {
            scanf("%d%d",&li[i],&ri[i]);
            x[nn++]=li[i],x[nn++]=ri[i];
        }
        sort(x,x+nn);
        int m=1;
        for(int i=1;i<nn;i++)
        {
            if(x[i]!=x[i-1]) x[m++]=x[i];
        }
        sort(x,x+m);
        memset(col,-1,sizeof(col));
        for(int i=0;i<n;i++)
        {
            int l=Bin(li[i],m);
            int r=Bin(ri[i],m);
            upDate(l,r,i,0,m-1,1);
        }
        ans=0;//用来记录颜色总数
        memset(hash,false,sizeof(hash));
        query(0,m-1,1);
        printf("%d\n",ans);
    }

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值