您的位置:首页 > 其它

HDU - 4553 约会安排(线段树 区间合并)

2015-10-21 23:18 429 查看
题目大意:中文题意

解题思路:设计三个mark,一个是女神的,一个是学习的,一个是基友的,其中优先级是学习<基友<女神,更新的时候按照优先级更新

区间维护六个数,一个是左连续的最长空闲时间,一个是右连续的最长空闲时间,一个是最长空闲时间,三个时间,一个是基友的,一个是女神的,所以共6个

询问的时候,如果是基友的话,直接判断总的基友的连续时间,如果时间够的话,就找出,输出并更新。反之,则另外输出

如果是女神的,先判断一下基友的连续时间,如果够的话,从中得到该时间,输出并修改

如果不够,就判断一下女神的连续时间

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010 << 2;

struct Tree{
int n, d, s;//女神标记n,屌丝标记d,学习标记s
int dls, drs, das;//屌丝的左连续最长,右连续最长,总连续最长
int nls, nrs, nas;//女神的左连续最长,右连续最长,总连续最长
}tree
;
int n, q;

void Diaosi(int u) {
tree[u].d = 1;
tree[u].dls = tree[u].drs = tree[u].das = 0;
}

void Nvshen(int u) {
tree[u].n = 1;
tree[u].d = 0;
tree[u].nls = tree[u].nrs = tree[u].nas = 0;
tree[u].dls = tree[u].drs = tree[u].das = 0;
}

void PushUp(int u, int l, int r) {
int mid = (l + r) >> 1;

tree[u].das = max(tree[u << 1].das, max(tree[u << 1 | 1].das, tree[u << 1].drs + tree[u << 1 | 1].dls));
tree[u].dls = tree[u << 1].dls;
tree[u].drs = tree[u << 1 | 1].drs;
if (tree[u].dls == mid - l + 1) tree[u].dls += tree[u << 1 | 1].dls;
if (tree[u].drs == r - mid) tree[u].drs += tree[u << 1].drs;

tree[u].nas = max(tree[u << 1].nas, max(tree[u << 1 | 1].nas, tree[u << 1].nrs + tree[u << 1 | 1].nls));
tree[u].nls = tree[u << 1].nls;
tree[u].nrs = tree[u << 1 | 1].nrs;
if (tree[u].nls == mid - l + 1) tree[u].nls += tree[u << 1 | 1].nls;
if (tree[u].nrs == r - mid) tree[u].nrs += tree[u << 1].nrs;
}

void StudyTime(int u, int l, int r) {
tree[u].s = 1;
tree[u].n = tree[u].d = 0;
tree[u].dls = tree[u].drs = tree[u].das = r - l + 1;
tree[u].nls = tree[u].nrs = tree[u].nas = r - l + 1;
}

void PushDown(int u, int l, int r) {
int mid = (l + r) >> 1;
if (tree[u].s) {
StudyTime(u << 1, l, mid);
StudyTime(u << 1 | 1, mid + 1, r);
tree[u].s = 0;
}

if (tree[u].d) {
Diaosi(u << 1);
Diaosi(u << 1 | 1);
tree[u].d = 0;
}

if (tree[u].n) {
Nvshen(u << 1);
Nvshen(u << 1 | 1);
tree[u].n = 0;
}
}

void study(int u, int l, int r, int L, int R) {
if (l == L && r == R) {
StudyTime(u, l, r);
return ;
}
int mid = (l + r) >> 1;
PushDown(u, l, r);
if (R <= mid) study(u << 1, l, mid, L, R);
else if (L > mid) study(u << 1 | 1, mid + 1, r, L, R);
else {
study(u << 1, l, mid, L, mid);
study(u << 1 | 1, mid + 1, r, mid + 1, R);
}
PushUp(u, l, r);
}

void Modify(int u, int l, int r, int L, int R, int f) {
if (l == L && r == R) {
if (f == 0) Diaosi(u);
else  Nvshen(u);
return ;
}
int mid = (l + r) >> 1;
PushDown(u, l, r);
if (R <= mid) Modify(u << 1, l, mid, L, R, f);
else if (L > mid) Modify(u << 1 | 1, mid + 1, r, L, R, f);
else {
Modify(u << 1, l, mid, L, mid, f);
Modify(u << 1 | 1, mid + 1, r, mid + 1, R, f);
}
PushUp(u, l, r);
}

int Query(int u, int l, int r, int w, int f) {
if (l == r) return l;
int mid = (l + r) >> 1;
PushDown(u, l, r);
if (f == 0) {
if (tree[u << 1].das >= w) return Query(u << 1, l, mid, w, f);
else if (tree[u << 1].drs + tree[u << 1 | 1].dls >= w) return mid - tree[u << 1].drs + 1;
else return Query(u << 1 | 1, mid + 1, r, w, f);
}
else {
if (tree[u << 1].nas >= w) return Query(u << 1, l, mid, w, f);
else if (tree[u << 1].nrs + tree[u << 1 | 1].nls >= w) return mid - tree[u << 1].nrs + 1;
else return Query(u << 1 | 1, mid + 1, r, w, f);
}
}

void solve() {
char op[10];
int x, y;
while (q--) {
scanf("%s", op);
if (op[0] == 'D') {
scanf("%d", &x);
if (tree[1].das < x) printf("fly with yourself\n");
else {
int ans = Query(1, 1, n, x, 0);
Modify(1, 1, n, ans, ans + x - 1, 0);
printf("%d,let's fly\n", ans);
}
}
else if (op[0] == 'N') {
scanf("%d", &x);
if (tree[1].das < x) {
if (tree[1].nas < x) printf("wait for me\n");
else {
int ans = Query(1, 1, n, x, 1);
Modify(1, 1, n, ans, ans + x - 1, 1);
printf("%d,don't put my gezi\n", ans);
}
}
else {
int ans = Query(1, 1, n, x, 0);
Modify(1, 1, n, ans, ans + x - 1, 1);
printf("%d,don't put my gezi\n", ans);
}
}
else {
scanf("%d%d", &x, &y);
study(1, 1, n, x, y);
printf("I am the hope of chinese chengxuyuan!!\n");
}
}
}

int main() {
int test, cas = 1;
scanf("%d", &test);
while (test--) {
printf("Case %d:\n", cas++);
scanf("%d%d", &n, &q);
study(1, 1, n, 1, n);
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: