HDU 1540 Tunnel Warfare

时间:2023-03-09 21:27:19
HDU 1540 Tunnel Warfare

HDU 1540

思路1:

树状数组+二分

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define ls rt<<1,l,m
#define rs rt<<1|1,m+1,r
#define mem(a,b) memset(a,b,sizeof(a)) const int N=5e4+;
int bit[N];
bool vis[N];
int n;
int add(int x,int a){
while(x<=n)bit[x]+=a,x+=x&-x;
}
int query(int x){
int ans=;
while(x)ans+=bit[x],x-=x&-x;
return ans;
}
bool check(int x,int m){
//cout<<query(m)<<' '<<query(x-1)<<endl;
if(query(m)-query(x-)<m-x+)return true;
else return false;
}
bool check1(int x,int m){
if(query(x)-query(m-)<x-m+)return true;
else return false;
}
int main(){
ios::sync_with_stdio(false);
cin.tie();
int m,x;
char c;
while(cin>>n>>m)
{
mem(bit,);
mem(vis,false);
for(int i=;i<=n;i++)add(i,);
stack<int>s;
for(int i=;i<=m;i++){
cin>>c;
if(c=='D'){
cin>>x;
if(!vis[x])add(x,-),vis[x]=true;
s.push(x);
}
else if(c=='Q'){
cin>>x;
int l=x,r=n,mid=(l+r)>>;
while(l<r){
//cout<<l<<' '<<r<<' '<<query(mid)<<' '<<query(x-1)<<endl;
if(check(x,mid))r=mid-;
else l=mid;
mid=(l+r+)>>; }
int R=mid;
l=,r=x,mid=(l+r)>>;
while(l<r){
if(check1(x,mid))l=mid+;
else r=mid;
mid=(l+r)>>;
}
int L=mid;
if(vis[x])cout<<<<endl;
else cout<<R-L+<<endl;
}
else{
if(vis[s.top()])add(s.top(),),vis[s.top()]=false;
s.pop();
}
}
}
return ;
}

思路2:

线段树区间合并

代码:

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define ls rt<<1,l,m
#define rs rt<<1|1,m+1,r
#define mem(a,b) memset(a,b,sizeof(a)) const int N=5e4+;
struct tree{
int ll,rr,len;//ll表示以当前区间左端点为左端点最长连续区间的长度,rr表示以当前区间右端点为右端点最长连续区间的长度,len表示当前区间的长度
}tree[N<<];
void push_up(int rt){
if(tree[rt<<].ll==tree[rt<<].len)tree[rt].ll=tree[rt<<].ll+tree[rt<<|].ll;
else tree[rt].ll=tree[rt<<].ll;
if(tree[rt<<|].rr==tree[rt<<|].len)tree[rt].rr=tree[rt<<|].rr+tree[rt<<].rr;
else tree[rt].rr=tree[rt<<|].rr;
}
void build(int rt,int l,int r){
tree[rt].ll=tree[rt].rr=tree[rt].len=r-l+;
if(l==r)return ;
int m=(l+r)>>;
build(ls);
build(rs);
}
void update(int p,int v,int rt,int l,int r){
if(l==r){
tree[rt].ll=tree[rt].rr=v;
return ;
}
int m=(l+r)>>;
if(p<=m)update(p,v,ls);
else update(p,v,rs);
push_up(rt);
}
int query(int p,int rt,int l,int r){
if(rt==){
if(l+tree[rt].ll->=p)return tree[rt].ll;
if(r-tree[rt].rr+<=p)return tree[rt].rr;
}
else{
if(l+tree[rt].ll->=p)return tree[rt].ll+tree[rt-].rr;
if(r-tree[rt].rr+<=p)return tree[rt].rr+tree[rt+].ll;
}
if(l==r)return ;
int m=(l+r)>>;
if(p<=m)return query(p,ls);
else return query(p,rs);
}
int main(){
ios::sync_with_stdio(false);
cin.tie();
int n,m,x;
char c;
while(cin>>n>>m){
stack<int>s;
build(,,n);
while(m--){
cin>>c;
if(c=='D'){
cin>>x;
s.push(x);
update(x,,,,n);
}
else if(c=='Q'){
cin>>x;
cout<<query(x,,,n)<<endl;
}
else{
x=s.top();
s.pop();
update(x,,,,n);
}
}
}
return ;
}