POJ 2777 线段树基础题

题意:

给你一个长度为N的线段数,一开始每个树的颜色都是1,然后有2个操作。

第一个操作,将区间[a , b ]的颜色换成c。

第二个操作,输出区间[a , b ]不同颜色的总数。

直接线段树搞之。不过输入有个坑,a 可能大于b ,所以要判断一下。

 

#include <iostream>

#include <cstdio>

#include <algorithm>

#include <string>

#include <cmath>

#include <cstring>

#include <queue>

#include <set>

#include <vector>

#include <stack>

#include <map>

#include <iomanip>

#define PI acos(-1.0)

#define Max 2505

#define inf 1<<28

#define LL(x) (x<<1)

#define RR(x) (x<<1|1)

#define REP(i,s,t) for(int i=(s);i<=(t);++i)

#define ll long long

#define mem(a,b) memset(a,b,sizeof(a))

#define mp(a,b) make_pair(a,b)

#define PII pair<int,int>

using namespace std;



int L[1111111] , R[1111111] , data[1111111] , add[1111111] ;

int vis[1111] ;

int ans ;

int n , T ,O ;

void push_up(int x){

    if(data[LL(x)] != data[RR(x)])

        data[x] = 50 ;

    else

    data[x] = data[LL(x)] ;

}

void build(int l ,int r ,int u){

    L[u] = l ;

    R[u] = r ;

    data[u] = 1 ;

    add[u] = 0 ;

    if(l == r)return ;

    int mid = l + r >> 1 ;

    build(l ,mid ,LL(u)) ;

    build(mid + 1 ,r ,RR(u)) ;

}



void push_down(int x){

    if(add[x]){

        add[LL(x)] = add[x] ;

        add[RR(x)] = add[x] ;

        data[LL(x)] = add[x] ;

        data[RR(x)] = add[x] ;

        add[x] = 0 ;

    }

}



void updata(int l ,int r ,int u ,int color){

    push_down(u) ;

    if(l > R[u] || r < L[u])return ;

    if(l == L[u] && r == R[u]){

        data[u] = color ;

        add[u] = color ;

        return ;

    }

    int mid = (L[u] + R[u]) >> 1 ;

    if(r <= mid)updata(l , r , LL(u) ,color) ;

    else if(l > mid)updata(l ,r ,RR(u) ,color) ;

    else {

        updata(l ,mid ,LL(u), color) ;

        updata(mid + 1 ,r ,RR(u) ,color) ;

    }

    push_up(u) ;

}



void query(int l ,int r ,int u){

    push_down(u) ;

    if(l > R[u] || r < L[u])return ;

    if(l == L[u] && r == R[u]){

        if(data[u] != 50){

            if(!vis[data[u]]){

                ans ++ ;

                vis[data[u]] = 1 ;

            }

            return ;

        }

    }

    int mid = L[u] + R[u] >> 1 ;

    if(l > mid )query(l ,r , RR(u)) ;

    else if(r <= mid)query(l, r ,LL(u)) ;

    else {

        query(l , mid ,LL(u)) ;

        query(mid + 1 ,r ,RR(u)) ;

    }

    push_up(u) ;

}

inline void RD(int &ret) {

    char c;

    do {

        c = getchar();

    } while(c < '0' || c > '9') ;

    ret = c - '0';

    while((c=getchar()) >= '0' && c <= '9')

        ret = ret * 10 + ( c - '0' );

}

void swap(int& a ,int& b){

    int temp = a ;

    if(a > b){

        a = b ;

        b = temp ;

    }

}

void debug(){

    for (int i = 1 ;i <= 3 * n ;i ++){

        cout << "L:" << L[i] << "R:" << R[i] << "data:" << data[i] << "add:" << add[i] << endl;

    }

}

int main() {

    cin >> n >> T >> O ;

    build(1 , n , 1 ) ;

    int a , b , c ;

    char op[11] ;

    while(O -- ){

        scanf("%s",op) ;

        if(op[0] == 'C'){

            scanf("%d%d%d",&a,&b,&c) ;

            if( a > b)swap(a ,b ) ;

            updata(a , b, 1 , c) ;

        }

        else if(op[0] == 'P'){

            scanf("%d%d",&a,&b) ;

            if(a > b)swap(a , b) ;

            ans = 0 ;

            mem(vis,0) ;

            query(a , b , 1) ;

            printf("%d\n",ans) ;

        }

    }

    return 0 ;

}


 

 

你可能感兴趣的:(poj)