现在的位置: 首页 > 综合 > 正文

Poj 2777 Count Color(线段树基础)

2014年02月24日 ⁄ 综合 ⁄ 共 2111字 ⁄ 字号 评论关闭

又毁三观了.......虽然题目数据有坑:区间【a,b】可能会有a>b的情况,但是我一开始没有考虑它也能过。

此外莫名其妙的TLE

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <climits>
#define MAX 100005
#define INF 0x7FFFFFFF
#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 L(x) x<<1
#define R(x) x<<1|1
# define eps 1e-5
//#pragma comment(linker, "/STACK:36777216") ///传说中的外挂
using namespace std;
struct node {
    int left,right,mid,value,add;
} edge[4*MAX];

int aa[MAX];
int vis[33];
int ans ;
void push_up(int x) {
    if(edge[R(x)].add != edge[L(x)].add)
        edge[x].add = 0;
}

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

    edge[num].left = l;
    edge[num].right = r;
    edge[num].mid = (l+r) >> 1;
    edge[num].add = 1;
    if(l == r) {
        edge[num].value = 1;
        return ;
    }

    build(l,edge[num].mid,num * 2); //左子树
    build(edge[num].mid + 1,r,num*2+1); //右子树

    push_up(num);

}

void push_down(int x) {
    if(edge[x].add) {
        //edge[L(x)].value = (edge[L(x)].right - edge[L(x)].left + 1 ) * edge[x].add ;
        //edge[R(x)].value = (edge[R(x)].right - edge[R(x)].left + 1) * edge[x].add ;
        edge[L(x)].add = edge[x].add ;
        edge[R(x)].add = edge[x].add ;
        edge[x].add = 0 ;
    }
}
void update(int l, int r, int k, int num) {
    if(edge[num].left >= l && edge[num].right <= r) {
        //当前区间包含于更新区间
        edge[num].add = k;
        return;
    }
    push_down(num);
    if(edge[num].mid < l) update(l, r, k, num*2+1);
    else if(edge[num].mid >= r) update(l, r, k, num*2);
    else {
        update(l, edge[num].mid, k, num*2);
        update(edge[num].mid + 1, r, k, num*2+1);
    }
    push_up(num);

}

void query(int l,int r,int num) {
    //if(l == edge[num].left && r == edge[num].right) //很想知道加了这个判断后TLE,不加400ms以内是为什么,按理加它是没有问题的......
        if(edge[num].add != 0) {
            if(vis[edge[num].add] == 0) {
                ans++;
                vis[edge[num].add] = 1;
            }
            return ;
        }
    push_down(num);
    if(r <= edge[num].mid)
        query(l,r,num*2);
    else if(l >= edge[num].mid + 1)
        query(l,r,num *2+1);
    else {
        query(l,edge[num].mid,num*2);
        query(edge[num].mid+1,r,num*2+1);
    }
}

int main() {

    int n,m,l,i,x,y,c;
    char str[3] ;
    cin >> n >> l >> m;
    build(1,n,1);
    for(i=1; i<=m; i++) {
        scanf("%s",str);
        if(str[0] == 'C') {
            scanf("%d%d%d",&x,&y,&c);
            if(x > y)
                swap(x,y);
            update(x,y,c,1);
        }
        if(str[0] == 'P') {
            ans = 0;
            scanf("%d%d",&x,&y);
            if(x > y)
                swap(x,y);
            mem(vis,0);
            query(x,y,1);
            printf("%d\n",ans);
        }

    }
    return 0;
}

抱歉!评论已关闭.