M - 约会安排 HDU - 4553 线段树 (最长连续段)

中文题面

思路:维和两个区间  一个是女神区间 一个是基友区间  如果是基友要预约时间 直接在基友区间查询可满足的起点 (这里先判tree[1].m >=length也就是有没有这样的区间满足时间length) 预约成功后更新基友区间

如果是女神要预约区间 先在基友区间预约看有没有满足的区间 (同样看根节点的m) 如果有 同时更新两个区间 如果没有继续在女神区间查找 如果女神区间有 则同时更新基友和女神区间 如果没有 那就真没有了直接输出 题目要求的话

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxn=1e6+5;
  4 struct Node{
  5     int l,r;
  6     int ml,mr,m;
  7 }tree1[maxn*4],tree2[maxn*4];
  8 void build(int x,int l,int r){
  9     tree1[x].l=tree2[x].l=l;
 10     tree1[x].r=tree2[x].r=r;
 11     tree1[x].ml=tree2[x].ml=tree1[x].mr=tree2[x].mr=tree1[x].m=tree2[x].m=r-l+1;
 12     if(l==r)return ;
 13     int mid=l+r>>1;
 14     build(x<<1,l,mid);
 15     build(x<<1|1,mid+1,r);
 16 }
 17 void push_up(int x){
 18     int mid=tree1[x].r+tree1[x].l>>1;
 19     tree1[x].ml=tree1[x<<1].ml;
 20     tree1[x].mr=tree1[x<<1|1].mr;
 21     tree1[x].m=max(max(tree1[x<<1].m,tree1[x<<1|1].m),tree1[x<<1].mr+tree1[x<<1|1].ml);
 22     if(tree1[x<<1].ml==mid-tree1[x].l+1)tree1[x].ml+=tree1[x<<1|1].ml;
 23     if(tree1[x<<1|1].mr==tree1[x].r-mid)tree1[x].mr+=tree1[x<<1].mr;
 24
 25     tree2[x].ml=tree2[x<<1].ml;
 26     tree2[x].mr=tree2[x<<1|1].mr;
 27     tree2[x].m=max(max(tree2[x<<1].m,tree2[x<<1|1].m),tree2[x<<1].mr+tree2[x<<1|1].ml);
 28     if(tree2[x<<1].ml==mid-tree2[x].l+1)tree2[x].ml+=tree2[x<<1|1].ml;
 29     if(tree2[x<<1|1].mr==tree2[x].r-mid)tree2[x].mr+=tree2[x<<1].mr;
 30
 31 }
 32 void push_down(int x){
 33     int mid=tree1[x].l+tree1[x].r>>1;
 34     if(tree1[x].m==tree1[x].r-tree1[x].l+1){
 35         tree1[x<<1].ml=tree1[x<<1].mr=tree1[x<<1].m=mid-tree1[x].l+1;
 36         tree1[x<<1|1].ml=tree1[x<<1|1].mr=tree1[x<<1|1].m=tree1[x].r-mid;
 37     }
 38     else if(tree1[x].m==0){
 39         tree1[x<<1].ml=tree1[x<<1].mr=tree1[x<<1].m=0;
 40         tree1[x<<1|1].ml=tree1[x<<1|1].mr=tree1[x<<1|1].m=0;
 41     }
 42
 43     if(tree2[x].m==tree2[x].r-tree2[x].l+1){
 44         tree2[x<<1].ml=tree2[x<<1].mr=tree2[x<<1].m=mid-tree2[x].l+1;
 45         tree2[x<<1|1].mr=tree2[x<<1|1].ml=tree2[x<<1|1].m=tree2[x].r-mid;
 46     }
 47     else if(tree2[x].m==0){
 48             tree2[x<<1].ml=tree2[x<<1].mr=tree2[x<<1].m=0;
 49         tree2[x<<1|1].mr=tree2[x<<1|1].ml=tree2[x<<1|1].m=0;
 50     }
 51 }
 52 void update(int x,int l,int r,int value){
 53     if(tree1[x].l>=l&&tree1[x].r<=r){
 54         if(value==1){
 55             tree1[x].ml=tree1[x].mr=tree1[x].m=0;
 56         }
 57         else if(value==2){
 58             tree1[x].ml=tree1[x].mr=tree1[x].m=0;
 59             tree2[x].ml=tree2[x].mr=tree2[x].m=0;
 60         }
 61         else {
 62             tree1[x].ml=tree1[x].mr=tree1[x].m=tree1[x].r-tree1[x].l+1;
 63             tree2[x].ml=tree2[x].mr=tree2[x].m=tree1[x].r-tree1[x].l+1;
 64         }
 65         return ;
 66     }
 67     int mid=tree1[x].l+tree1[x].r>>1;
 68     push_down(x);
 69     if(mid>=l)update(x<<1,l,r,value);
 70     if(mid<r)update(x<<1|1,l,r,value);
 71     push_up(x);
 72 }
 73 int  query(int x,int length,int value){
 74     if(tree1[x].l==tree1[x].r)return tree1[x].l;
 75     push_down(x);
 76     int mid=tree1[x].l+tree1[x].r>>1;
 77     if(value==1){
 78         if(tree1[x<<1].m>=length){
 79             return query(x<<1,length,value);
 80         }
 81         else if(tree1[x<<1].mr+tree1[x<<1|1].ml>=length){
 82             return mid-tree1[x<<1].mr+1;
 83         }
 84         else return query(x<<1|1,length,value);
 85     }
 86     else {
 87             if(tree2[x<<1].m>=length){
 88             return query(x<<1,length,value);
 89         }
 90         else if(tree2[x<<1].mr+tree2[x<<1|1].ml>=length){
 91             return mid-tree2[x<<1].mr+1;
 92         }
 93         else return query(x<<1|1,length,value);
 94     }
 95 }
 96 int main(){
 97     int t;
 98     int kase=1;
 99     scanf("%d",&t);
100     char s[100];
101     int temp;
102     int q;
103     int  n;
104     while(t--){
105         printf("Case %d:\n",kase++);
106         scanf("%d%d",&n,&q);
107         build(1,1,n);
108         while(q--){
109             scanf("%s%d",s,&temp);
110             if(s[0]==‘D‘){
111                 if(tree1[1].m>=temp){
112                     int start=query(1,temp,1);
113                     update(1,start,start+temp-1,1);
114                  printf("%d,let‘s fly\n",start);
115                 }
116                 else printf("fly with yourself\n");
117             }
118             else if(s[0]==‘N‘){
119                 if(tree1[1].m>=temp){
120                     int start=query(1,temp,1);
121                     update(1,start,start+temp-1,2);
122                  printf("%d,don‘t put my gezi\n",start);
123                 }
124                 else if(tree2[1].m>=temp){
125                     int start=query(1,temp,0);
126                     update(1,start,start+temp-1,2);
127                  printf("%d,don‘t put my gezi\n",start);
128                 }
129                 else   printf("wait for me\n");
130             }
131             else {
132                 int zz;
133                 scanf("%d",&zz);
134                 update(1,temp,zz,3);
135                 printf("I am the hope of chinese chengxuyuan!!\n");
136             }
137         }
138
139     }
140     return 0;
141 }

原文地址:https://www.cnblogs.com/ttttttttrx/p/10349570.html

时间: 2024-08-03 07:12:39

M - 约会安排 HDU - 4553 线段树 (最长连续段)的相关文章

HDU 4553 约会安排(二维线段树)

Problem Description 寒假来了,又到了小明和女神们约会的季节. 小明虽为屌丝级码农,但非常活跃,女神们常常在小明网上的大段发言后热情回复"呵呵",所以,小明的最爱就是和女神们约会.与此同时,也有很多基友找他开黑,由于数量实在过于巨大,怎么安排时间便成了小明的一大心事. 我们已知小明一共有T的空闲时间,期间会有很多女神或者基友来找小明. 作为一个操作系统曾经怒考71分的大神,小明想到了一个算法,即"首次适应算法",根据操作系统课本的描述,就是找一段最

约会安排---hdu4553(线段树,麻烦的区间覆盖)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4553 算是poj3667的加强版,建立两颗线段树,一个是DS区间,另一个是NS区间.那么根据题意,如果是DS的请求,那么首先查找DS的区间,如果有满足的区间就更新DS区间,NS的区间不需要更新.如果是NS的请求,首先看DS区间是否有满足的区间,否则查找NS区间,如果有就同时更新DS区间和NS区间.那么可以归纳为,只要是NS的请求,就同时更新两颗线段树,否则只更新DS的线段树. 注意输出要从Outpu

hdu 4553 约会安排 (两个线段树维护区间)

include include include include include include include include define ll long long define FOR(i,l,r) for(int i = l ; i <= r ;++i ) define inf 1<<30 define EPS (1e-9) define lson(p) (p<<1) define rson(p) (p<<1|1) using namespace std;

M - 约会安排 - hdu 4553

寒假来了,又到了小明和女神们约会的季节.  小明虽为?丝级码农,但非常活跃,女神们常常在小明网上的大段发言后热情回复“呵呵”,所以,小明的最爱就是和女神们约会.与此同时,也有很多基友找他开黑,由于数量实在过于巨大,怎么安排时间便成了小明的一大心事.  我们已知小明一共有T的空闲时间,期间会有很多女神或者基友来找小明.  作为一个操作系统曾经怒考71分的大神,小明想到了一个算法,即“首次适应算法”,根据操作系统课本的描述,就是找一段最靠前的符合要求的连续空间分配给每个请求,由此小明做出了一个决定:

HDU 4553 线段树双关键字区间合并

用两个关键字记录,分别为屌丝时间和女神时间 若屌丝约,更新屌丝时间 若女神约,更新屌丝和女神时间 学习,则两个全部清空 #include "stdio.h" #include "string.h" struct Data { int l,r,x1,x2,l1,l2,r1,r2; }data[400010]; int Max(int a,int b) { if (a<b) return b;else return a; } void build(int l,in

HDU 4893 线段树裸题

Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2512    Accepted Submission(s): 751 Problem Description Recently, Doge got a funny birthday present from his new friend, Pro

HDU 4902 线段树(区间更新)

Nice boat Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 353    Accepted Submission(s): 169 Problem Description There is an old country and the king fell in love with a devil. The devil alw

hdu 4893 线段树 --- 也是两个变 类似双标记

http://acm.hdu.edu.cn/showproblem.php?pid=4893 开始的时候,我按双标记,WA了一下午,搞不定,我是用的两个标记add--表示当前结点中有值发生变化,flag,斐波那契的懒惰标记,但是估计是我自己处理的有问题,一直不对 参考了别人的代码,写法还是很不错的,Add变量维护的是,完全变成Fibonacci的时候的和,---回头我再重新写一遍 #include <cstdio> #include <cstring> #include <a

HDU 4902 线段树||暴力

给定一个序列,两种操作 1:把一段变成x. 2:把一段每个数字,如果他大于x,就变成他和x的gcd,求变换完后,最后的序列. 线段树解法:用lazy标记下即可,优化方法还是很巧妙的, Accepted 4902 515MS 3308K 1941 B C++ #include "stdio.h" #include "string.h" struct node { int l,r,x;// 在叶子节点代表值,树节点代表成端更新的lazy操作. }data[400010]