POJ:2528 Mayor's posters(未AC)

这是经典的线段树染色问题。用到了区间改值。

这个题的难点在于离散化。普通的离散化是不行的。因为在线段树和这个题中数字代表的是一段区间,这样4和5是相邻的。而且普通的离散化每个数都是相邻的。如果有两个区间

【1,6】,【10,20】,【1,20】。离散化以后就变成【1,2】【3,4】,【1,4】。很明显两个答案并不一样。这样,如果相邻两个点的差值大于1,则离散化的时候编号多加一。

POJ的disscuss上说这题数据有问题。我也不知道是否是真的。我下面的代码在POJ上WA了。

在http://acm.nyist.net/JudgeOnline/problem.php?pid=9上面AC了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#define ll long long
#define INF 2139062143
#define inf -2139062144
#define MOD 20071027
#define MAXN 100005
#define LEN 222222<<2
using namespace std;
set<int> cnt;
struct Line_Tree
{
private:
    int setv[LEN];
    int sv,ql,qr,sz;
    void PushDown(int o)
    {
        if(setv[o])
        {
            setv[o<<1|1]=setv[o<<1]=setv[o];
            setv[o]=0;
        }
    }
    void myupdate(int o,int L,int R)
    {
        if(ql<=L&&R<=qr)
        {
            setv[o]=sv;
            return ;
        }
        PushDown(o);
        int M=(L+R)>>1;
        if(ql<=M) myupdate(o<<1,L,M);
        if(M<qr) myupdate(o<<1|1,M+1,R);
    }
    void myquery(int o,int L,int R)
    {
        if(L==R)
        {
            cnt.insert(setv[o]);
            return ;
        }
        PushDown(o);
        int M=(L+R)>>1;
        if(ql<=M)
            myquery(o<<1,L,M);
        if(M<qr)
            myquery(o<<1|1,M+1,R);
    }
public:
    void init(int n)
    {
        sz=n;
    }
    void clear(int o,int L,int R)
    {
        setv[o]=0;
        if(L==R) return ;
        int M=(L+R)>>1;
        clear(o<<1,L,M);
        clear(o<<1|1,M+1,R);
    }
    void update(int v,int L,int R)
    {
        sv=v;
        ql=L;
        qr=R;
        myupdate(1,1,sz);
    }
    int solve()
    {
        cnt.clear();
        ql=1;
        qr=sz;
        myquery(1,1,sz);
        return cnt.size();
    }
};
Line_Tree tree;
map<int,int> has;
int s;
int ID(int val)
{
    if(!has[val]) return has[val]=++s;
    return has[val];
}
vector<int> arr;
vector<pair <int,int> > vec;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        has.clear();
        arr.clear();
        vec.clear();
        for(int i=0; i<n; ++i)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            vec.push_back(pair<int,int>(x,y));
            arr.push_back(x);
            arr.push_back(y);
        }
        sort(arr.begin(),arr.end());
        s=0;
        for(int i=0; i<arr.size(); ++i)
        {
            if(i&&arr[i]==arr[i-1] ) continue;
            if(i&&arr[i]-arr[i-1]>1) s++;
            ID(arr[i]);
        }
        tree.init(s);
        tree.clear(1,1,s);
        for(int i=0; i<vec.size(); ++i)
            tree.update(i+1,has[vec[i].first],has[vec[i].second]);
        printf("%d\n",tree.solve());
    }
    return 0;
}


 

你可能感兴趣的:(POJ:2528 Mayor's posters(未AC))