您的位置:首页 > 其它

【HDOJ】4553 约会安排

2015-10-25 13:17 429 查看
线段树。线段树的细节很重要,小数据遍历可以发现问题。

/* 4553 */
#include <iostream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000")

#define sti                set<int>
#define stpii            set<pair<int, int> >
#define mpii            map<int,int>
#define vi                vector<int>
#define pii                pair<int,int>
#define vpii            vector<pair<int,int> >
#define rep(i, a, n)     for (int i=a;i<n;++i)
#define per(i, a, n)     for (int i=n-1;i>=a;--i)
#define clr                clear
#define pb                 push_back
#define mp                 make_pair
#define fir                first
#define sec                second
#define all(x)             (x).begin(),(x).end()
#define SZ(x)             ((int)(x).size())
#define lson            l, mid, rt<<1
#define rson            mid+1, r, rt<<1|1

typedef struct {
int l, r;
int nls, nrs, nms;
int dls, drs, dms;
} node_t;

const int study = 0;
const int ds = 1;
const int ns = 2;
const int maxn = 1e5+5;
node_t nd[maxn<<2];

void Build(int l, int r, int rt) {
nd[rt].l = l;
nd[rt].r = r;
nd[rt].nls = nd[rt].nrs = nd[rt].nms = r-l+1;
nd[rt].dls = nd[rt].drs = nd[rt].dms = r-l+1;
if (l == r)
return ;

int mid = (l + r) >> 1;
Build(lson);
Build(rson);
}

void PushDown(int rt) {
int l = nd[rt].l, r = nd[rt].r;
if (l == r)    return ;
int lb = rt<<1;
int rb = lb |1;
int mid = (l + r) >> 1;

if (nd[rt].dms == 0) {
nd[lb].dls = nd[lb].drs = nd[lb].dms = 0;
nd[rb].dls = nd[rb].drs = nd[rb].dms = 0;
} else if (nd[rt].dms == r-l+1) {
nd[lb].dls = nd[lb].drs = nd[lb].dms = mid - l + 1;
nd[rb].dls = nd[rb].drs = nd[rb].dms = r - mid;
}

if (nd[rt].nms == 0) {
nd[lb].nls = nd[lb].nrs = nd[lb].nms = 0;
nd[rb].nls = nd[rb].nrs = nd[rb].nms = 0;
} else if (nd[rt].nms == r-l+1) {
nd[lb].nls = nd[lb].nrs = nd[lb].nms = mid - l + 1;
nd[rb].nls = nd[rb].nrs = nd[rb].nms = r - mid;
}
}

void PushUp1(int rt) {
int l = nd[rt].l, r = nd[rt].r;
if (l == r)    return ;
int lb = rt<<1;
int rb = lb |1;
int mid = (l + r) >> 1;

nd[rt].dls = nd[lb].dls;
nd[rt].drs = nd[rb].drs;
nd[rt].dms = max(nd[lb].dms, nd[rb].dms);
nd[rt].dms = max(nd[rt].dms, nd[lb].drs+nd[rb].dls);

if (nd[lb].dls == mid - l + 1)
nd[rt].dls += nd[rb].dls;
if (nd[rb].drs == r - mid)
nd[rt].drs += nd[lb].drs;
}

void PushUp2(int rt) {
int l = nd[rt].l, r = nd[rt].r;
if (l == r)    return ;
int lb = rt<<1;
int rb = lb |1;
int mid = (l + r) >> 1;

nd[rt].nls = nd[lb].nls;
nd[rt].nrs = nd[rb].nrs;
nd[rt].nms = max(nd[lb].nms, nd[rb].nms);
nd[rt].nms = max(nd[rt].nms, nd[lb].nrs+nd[rb].nls);

if (nd[lb].nls == mid - l + 1)
nd[rt].nls += nd[rb].nls;
if (nd[rb].nrs == r - mid)
nd[rt].nrs += nd[lb].nrs;
}

int query1(int qt, int rt) {
PushDown(rt);

if (nd[rt].dms < qt)
return 0;

if (nd[rt].dls >= qt)
return nd[rt].l;

if (nd[rt<<1].dms >= qt)
return query1(qt, rt<<1);

if (nd[rt<<1].drs + nd[rt<<1|1].dls >= qt)
return nd[rt<<1].r - nd[rt<<1].drs + 1;

return query1(qt, rt<<1|1);
}

int query2(int qt, int rt) {
PushDown(rt);

if (nd[rt].nms < qt)
return 0;

if (nd[rt].nls >= qt)
return nd[rt].l;

if (nd[rt<<1].nms >= qt)
return query2(qt, rt<<1);

if (nd[rt<<1].nrs + nd[rt<<1|1].nls >= qt)
return nd[rt<<1].r - nd[rt<<1].nrs + 1;

return query2(qt, rt<<1|1);
}

void update0(int L, int R, int rt) {
if (L<=nd[rt].l && nd[rt].r<=R) {
nd[rt].nls = nd[rt].nrs = nd[rt].nms = nd[rt].r-nd[rt].l+1;
nd[rt].dls = nd[rt].drs = nd[rt].dms = nd[rt].r-nd[rt].l+1;
return ;
}

PushDown(rt);
int mid = (nd[rt].l + nd[rt].r) >> 1;

if (mid >= R) {
update0(L, R, rt<<1);
} else if (mid < L) {
update0(L, R, rt<<1|1);
} else {
update0(L, R, rt<<1);
update0(L, R, rt<<1|1);
}

PushUp1(rt);
PushUp2(rt);
}

void update1(int L, int R, int rt) {
if (L<=nd[rt].l && nd[rt].r<=R) {
nd[rt].dls = nd[rt].drs = nd[rt].dms = 0;
return ;
}

PushDown(rt);
int mid = (nd[rt].l + nd[rt].r) >> 1;

if (mid >= R) {
update1(L, R, rt<<1);
} else if (mid < L) {
update1(L, R, rt<<1|1);
} else {
update1(L, R, rt<<1);
update1(L, R, rt<<1|1);
}

PushUp1(rt);
}

void update2(int L, int R, int rt) {
if (L<=nd[rt].l && nd[rt].r<=R) {
nd[rt].nls = nd[rt].nrs = nd[rt].nms = 0;
nd[rt].dls = nd[rt].drs = nd[rt].dms = 0;
return ;
}

PushDown(rt);
int mid = (nd[rt].l + nd[rt].r) >> 1;

if (mid >= R) {
update2(L, R, rt<<1);
} else if (mid < L) {
update2(L, R, rt<<1|1);
} else {
update2(L, R, rt<<1);
update2(L, R, rt<<1|1);
}

PushUp1(rt);
PushUp2(rt);
}

int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif

int t;
int n, q;
int qt, l, r, ans;
char cmd[10];

scanf("%d", &t);
rep(tt, 1, t+1) {
scanf("%d %d", &n, &q);
Build(1, n, 1);
printf("Case %d:\n", tt);
while (q--) {
scanf("%s", cmd);
if (cmd[0] == 'S') {
scanf("%d %d", &l, &r);
update0(l, r, 1);
puts("I am the hope of chinese chengxuyuan!!");
} else if (cmd[0] == 'D') {
scanf("%d", &qt);
l = query1(qt, 1);
if (l == 0) {
puts("fly with yourself");
} else {
printf("%d,let's fly\n", l);
update1(l, l+qt-1, 1);
}
} else if (cmd[0] == 'N') {
scanf("%d", &qt);
l = query1(qt, 1);
if (l == 0)
l = query2(qt, 1);
if (l == 0) {
puts("wait for me");
} else {
printf("%d,don't put my gezi\n", l);
update2(l, l+qt-1, 1);
}
}
}
}

#ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: