你最愿意做的哪件事,才是你的天赋所在

0%

HDU4553-线段树

题目链接

HDU4553

思路

建立两颗线段树,发现NS的可以用DS的,而DS确不可以用女神的,在更新和查询的时候判断一下就好。
然后是区间连续和的板子题了。
前缀后缀,中间找。
以及两个lazy标记的影响要注意就好了
查询的时候,先查左,再到中间,最后右边。因为要求起始标号最小。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2e5+10;
struct node
{
int l,r;
int pre,suf;
int val;
bool clear;
bool full;
int len()
{
return r-l+1;
}
}DStree[maxn<<2],NStree[maxn<<2];
void PushUp(node *tree,int rt)
{
tree[rt].pre=tree[rt<<1].pre;
tree[rt].suf=tree[rt<<1|1].suf;
if(tree[rt].pre==tree[rt<<1].len())tree[rt].pre+=tree[rt<<1|1].pre;
if(tree[rt].suf==tree[rt<<1|1].len())tree[rt].suf+=tree[rt<<1].suf;
tree[rt].val=max(tree[rt<<1|1].val,max(tree[rt<<1].val,tree[rt<<1].suf+tree[rt<<1|1].pre));
}
void PushDown(node *tree,int rt)
{ if(tree[rt].len()==1)return ;
if(tree[rt].clear)
{
tree[rt<<1].pre=tree[rt<<1|1].pre=tree[rt<<1].suf=tree[rt<<1|1].suf=tree[rt<<1].val=tree[rt<<1|1].val=0;
tree[rt<<1|1].clear=tree[rt<<1].clear=true;
tree[rt<<1|1].full=tree[rt<<1].full=false;
tree[rt].clear=false;
}
if(tree[rt].full)
{
tree[rt<<1].pre=tree[rt<<1].suf=tree[rt<<1].val=tree[rt<<1].len();
tree[rt<<1|1].pre=tree[rt<<1|1].suf=tree[rt<<1|1].val=tree[rt<<1|1].len();
tree[rt<<1].full=tree[rt<<1|1].full=true;
tree[rt<<1|1].clear=tree[rt<<1|1].clear=false;
tree[rt].full=false;
}
}
void build(node *tree,int rt,int l,int r)
{
tree[rt].l=l;
tree[rt].r=r;
tree[rt].pre=tree[rt].suf=tree[rt].val=tree[rt].len();
tree[rt].full=0;
tree[rt].clear=0;
if(l==r)
{
tree[rt].val=tree[rt].suf=tree[rt].pre=1;
return ;
}
int mid = (l+r)>>1;
build(tree,rt<<1,l,mid);
build(tree,rt<<1|1,mid+1,r);
PushUp(tree,rt);
}
void Update(node *tree,int rt,int l,int r,int c)
{
if(tree[rt].l>r||tree[rt].r<l)return ;
if(tree[rt].l>=l&&tree[rt].r<=r)
{
if(c==1)
{
tree[rt].full=1;
tree[rt].clear=0;
tree[rt].pre=tree[rt].suf=tree[rt].val=tree[rt].len();
}
else
{
tree[rt].full=0;
tree[rt].clear=1;
tree[rt].pre=tree[rt].suf=tree[rt].val=0;
}
return ;
}
PushDown(tree,rt);
Update(tree,rt<<1,l,r,c);
Update(tree,rt<<1|1,l,r,c);
PushUp(tree,rt);
}
int query(node *tree,int rt,int len)
{ if(tree[rt].val<len)return -1;
if(tree[rt].l==tree[rt].r)return tree[rt].l;
PushDown(tree,rt);
int mid = (tree[rt].r+tree[rt].l)>>1;
if(tree[rt<<1].val>=len)
return query(tree,rt<<1,len);
else if(tree[rt<<1].suf+tree[rt<<1|1].pre>=len)return mid-tree[rt<<1].suf+1;
else query(tree,rt<<1|1,len);
}
int main()
{
int t;
scanf("%d",&t);
char s[100];
for(int cas=1;cas<=t;cas++)
{
printf("Case %d:\n",cas);
int n,m;
scanf("%d %d",&n,&m);
build(DStree,1,1,n);
build(NStree,1,1,n);
while(m--)
{
scanf("%s",s);
if(s[0]=='D')
{
int x;
scanf("%d",&x);
if(DStree[1].val<x)printf("fly with yourself\n");
else
{
int ans = query(DStree,1,x);
printf("%d,let's fly\n",ans);
Update(DStree,1,ans,ans+x-1,0);
}
}
if(s[0]=='N')
{
int x;
scanf("%d",&x);
if(DStree[1].val<x)
{
if(NStree[1].val<x) printf("wait for me\n");
else
{
int ans = query(NStree,1,x);
printf("%d,don't put my gezi\n",ans);
Update(DStree,1,ans,ans+x-1,0);
Update(NStree,1,ans,ans+x-1,0);
}
}
else
{
int ans = query(DStree,1,x);
printf("%d,don't put my gezi\n",ans);
Update(DStree,1,ans,ans+x-1,0);
Update(NStree,1,ans,ans+x-1,0);
}
}
if(s[0]=='S')
{
int x,y;
scanf("%d %d",&x,&y);
printf("I am the hope of chinese chengxuyuan!!\n");
Update(DStree,1,x,y,1);
Update(NStree,1,x,y,1);
}
}
}
}
-------------你最愿意做的哪件事才是你的天赋所在-------------