线段树二分

线段树二分线段树二分 Problem 4553 hdu edu cn 用 2 个线段树分别维护男生预约的时间段和女生预约的时间段 线段树里面保存的是最大连续子段和 空闲时间为 1 预约了的话就是 0 当男生来预约的时候 只需要修改男生的线段树即可 而当女生来预约的时候若在男生的线段树里面找不到空闲时间再去女生线段树里面查找

大家好,我是讯享网,很高兴认识大家。

线段树二分

Problem - 4553 (hdu.edu.cn)

用2个线段树分别维护男生预约的时间段和女生预约的时间段。


讯享网

线段树里面保存的是最大连续子段和,空闲时间为1,预约了的话就是0。
当男生来预约的时候,只需要修改男生的线段树即可。 而当女生来预约的时候若在男生的线段树里面找不到空闲时间再去女生线段树里面查找,若找到就修改男生和女生2个线段树(因为女生可以无视基友)。
每次查询修改时候进行区间下放。
查询的时候分成3种情况,首先如果调用查询函数代表一定有那么多空闲时间。
1.在左区间
2.左边区间和右边区间合并得来的答案,这种情况直接返回这个区间的左端点即可。
3.在右区间

#include<iostream> #include<algorithm> using namespace std; const int MAXN = 2e6 + 10; struct tnode { int l, r; int lazy; int lmx, rmx, ans;//最大子段和 tnode friend operator +(tnode a, tnode b) { tnode res; res.l = a.l; res.r = b.r; res.lazy=-1; res.lmx = a.lmx + (a.lmx == (a.r - a.l + 1) ? b.lmx : 0); res.rmx = b.rmx + (b.rmx == (b.r - b.l + 1) ? a.rmx : 0); res.ans = max(max(a.ans, b.ans), max(res.lmx, res.rmx)); res.ans=max(res.ans,a.rmx+b.lmx); return res; } }; int n, m; struct segment_tree { #define lch (root<<1) #define rch (root<<1|1) #define mid (t[root].l+t[root].r>>1) tnode t[MAXN<<2]; void pushup(int root) { t[root] = t[lch] + t[rch]; } void pushdown(int root) { if (t[root].lazy == -1)return; t[lch].lazy = t[root].lazy; t[lch].lmx = t[lch].rmx = t[lch].ans =(t[lch].r - t[lch].l + 1) * t[root].lazy; t[rch].lazy = t[root].lazy; t[rch].lmx = t[rch].rmx = t[rch].ans =(t[rch].r - t[rch].l + 1) * t[root].lazy; t[root].lazy = -1; } void build(int root, int l, int r) { t[root].l = l; t[root].r = r; t[root].lazy = -1; if (l == r) { t[root].lmx = t[root].rmx = t[root].ans =1; return; } build(lch, l, mid); build(rch, mid + 1, r); pushup(root); } void fugai(int root, int ql, int qr, int v) { if (t[root].l > qr || t[root].r < ql)return; if (t[root].l >= ql && t[root].r <= qr) { t[root].lazy = v; t[root].lmx = t[root].rmx = t[root].ans = (t[root].r - t[root].l + 1) * v; return; } pushdown(root); fugai(lch, ql, qr, v); fugai(rch, ql, qr, v); pushup(root); } void ask(int root,int len,int &res) { if(t[root].l==t[root].r){res=min(t[root].l,res);return;} pushdown(root); if(t[lch].ans>=len)ask(lch,len,res); else if(t[lch].rmx+t[rch].lmx>=len)res=min(res,(mid-t[lch].rmx+1)); else if(t[rch].ans>=len)ask(rch,len,res); pushup(root); return; } int ask(int root,int len) { if(t[root].l==t[root].r)return t[root].l; pushdown(root); if(t[lch].ans>=len)return ask(lch,len); else if(t[lch].rmx+t[rch].lmx>=len)return mid-t[lch].rmx+1; else return ask(rch,len); } #undef lch #undef rch #undef mid }man,weman; int main() { int T; scanf("%d", &T); for (int ci = 1; ci <= T; ci++) { scanf("%d%d", &n, &m); man.build(1, 1, n); weman.build(1, 1, n); printf("Case %d:\n", ci); for (int i = 1; i <= m; i++) { char s[33]; int x,y; scanf("%s%d", s, &x); if (s[0] == 'D') { if (man.t[1].ans >= x) { int t=man.ask(1,x); man.fugai(1,t,t+x-1,0); printf("%d,let's fly\n", t); } else { printf("fly with yourself\n"); } } else if (s[0] == 'N') { if (man.t[1].ans >= x) { int t=man.ask(1,x); man.fugai(1,t,t+x-1,0); weman.fugai(1,t,t+x-1,0); printf("%d,don't put my gezi\n", t); } else if (weman.t[1].ans >= x) { int t=weman.ask(1,x); weman.fugai(1,t,t+x-1,0); man.fugai(1,t,t+x-1,0); printf("%d,don't put my gezi\n", t); } else { printf("wait for me\n"); } } else { scanf("%d", &y); man.fugai(1,x,y,1); weman.fugai(1,x,y,1); printf("I am the hope of chinese chengxuyuan!!\n"); } } } return 0; } 

讯享网
小讯
上一篇 2025-02-17 23:13
下一篇 2025-01-12 09:45

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/34402.html