【线段树】 HDOJ 3627 Giant For

来源:互联网 发布:桂永清知乎 编辑:程序博客网 时间:2024/06/09 05:21

CF原题。。。刚开始做的时候SB的线段树套set。。。。结果在HDOJ上MLE。。。CF上TLE。。。后来换了姿势在HDOJ上过了。。。。但是CF还是TLE啊。。。优化不了了,求大牛指点。。。

#include <iostream>#include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits>#include <cstdlib>#include <cmath>#include <time.h>#define maxn 200005#define maxm 1000005#define eps 1e-10#define mod 1000000007#define INF 0x3f3f3f3f#define PI (acos(-1.0))#define lowbit(x) (x&(-x))#define mp make_pair#define ls o<<1#define rs o<<1 | 1#define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R//#pragma comment(linker, "/STACK:16777216")typedef long long LL;typedef unsigned long long ULL;//typedef int LL;using namespace std;LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;}LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;}// headstruct node{    int x, y, k, id;}p[maxn];char ss[maxn];int x[maxn];int maxv[maxn << 2];set<int> s[maxn];set<int>::iterator it;int cnt, n, ans_x, ans_y;int cmp1(node a, node b){    return a.x < b.x;}int cmp2(node a, node b){    return a.id < b.id;}void init(void){    for(int i = 0; i < maxn; i++) s[i].clear();}void read(void){    for(int i = 1; i <= n; i++) {        scanf("%s%d%d", ss, &p[i].x, &p[i].y);        if(ss[0] == 'a') p[i].k = 1;        if(ss[0] == 'r') p[i].k = 2;        if(ss[0] == 'f') p[i].k = 3;        p[i].id = i;    }    sort(p+1, p+n+1, cmp1);    for(int i = 1; i <= n; i++) x[i] = p[i].x;    int j = 2;    for(int i = 2; i <= n; i++) if(x[i] != x[i-1]) x[j++] = x[i];    cnt = j-1;    for(int i = 1; i <= n; i++) p[i].x = lower_bound(x+1, x+cnt+1, p[i].x) - x;    sort(p+1, p+n+1, cmp2);}void pushup(int o){    maxv[o] = max(maxv[ls], maxv[rs]);}void build(int o, int L, int R){    maxv[o] = -1;    if(L == R) return;    int mid = (L + R) >> 1;    build(lson);    build(rson);    pushup(o);}void add(int o, int L, int R, int pos, int x){        if(L == R) {        maxv[o] = max(maxv[o], x);            return;    }    int mid = (L + R) >> 1;    if(pos <= mid) add(lson, pos, x);    else add(rson, pos, x);    pushup(o);}void remove(int o, int L, int R, int pos, int x){    if(L == R) {        if(s[L].empty()) maxv[o] = -1;        else maxv[o] = *(--s[L].end());        return;    }    int mid = (L + R) >> 1;    if(pos <= mid) remove(lson, pos, x);    else remove(rson, pos, x);    pushup(o);}void query(int o, int L, int R, int ql, int qr, int y){    if(ans_x != -1) return;    if(L == R) {        if(maxv[o] <= y) return;        ans_y = *(upper_bound(s[L].begin(), s[L].end(), y));        ans_x = L;        return;    }    int mid = (L + R) >> 1;    if(ql <= L && qr >= R) {        if(maxv[o] <= y) return;        else {            query(lson, ql, qr, y);            query(rson, ql, qr, y);        }    }    if(ql <= mid) query(lson, ql, qr, y);    if(qr > mid) query(rson, ql, qr, y);}void work(void){    build(1, 1, cnt+1);    for(int i = 1; i <= n; i++) {        if(p[i].k == 1) {            s[p[i].x].insert(p[i].y);            add(1, 1, cnt + 1, p[i].x, p[i].y);                }        if(p[i].k == 2) {            s[p[i].x].erase(p[i].y);            remove(1, 1, cnt + 1, p[i].x, p[i].y);        }        if(p[i].k == 3) {            ans_x = ans_y = -1;            query(1, 1, cnt + 1, p[i].x+1, cnt + 1, p[i].y);            if(ans_x == -1) printf("-1\n");            else printf("%d %d\n", x[ans_x], ans_y);        }    }}int main(void){    int _ = 0;    while(scanf("%d", &n), n != 0) {        init();        read();        if(_) printf("\n");                printf("Case %d:\n", ++_);        work();    }    return 0;}


0 0
原创粉丝点击