文章目录
超级马里奥
hdu4417
正解是用可持久化线段树,时间复杂度 nlogn
但是这题的数据好像比较弱,用莫队 nsqrt(n)logn也能过。
树套树:
#include <bits/stdc++.h>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
#define mk(x,y) make_pair(x,y)
const int N =100100,inf=0x3f3f3f3f;
struct node {
int l,r;
tree<pair<int,int>,null_type,less<pair<int,int> >,rb_tree_tag,tree_order_statistics_node_update>t;
}tr[N*4];
int a[N];
void creat(int rt,int l,int r){
tr[rt].l=l,tr[rt].r=r;
for( int i=l;i<=r;i++){
tr[rt].t.insert(mk(a[i],i));
}
if(l==r) return ;
int mid=(l+r)/2;
creat(rt*2,l,mid);
creat(rt*2+1,mid+1,r);
return ;
}
int qq( int rt,int x,int L,int R){
int l=tr[rt].l,r=tr[rt].r;
int res=0;
if(l>=L&&r<=R){
res=tr[rt].t.order_of_key(mk(x,inf));
return res;
}
if(r<L||l>R) return 0;
int mid=(l+r)/2;
if(L<=mid) res+=qq(rt*2,x,L,R);
if(R>mid) res+=qq(rt*2+1,x,L,R);
return res;
}
void solve(){
int n,m;
cin>>n>>m;
for( int i=1;i<=n;i++) scanf("%d",&a[i]);
creat(1,1,n);
for( int i=1;i<=m;i++){
int l,r,x;
cin>>l>>r>>x;
printf("%d\n",qq(1,x,++l,++r));
}
}
int main(){
int t;
cin>>t;
for( int i=1;i<=t;i++){
printf("Case %d:\n",t);
solve();
}
return 0;
}
莫队:
#include <bits/stdc++.h>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
const int N= 100100;
const int inf=0x3f3f3f3f;
const int sq=330;
int a[N],ans[N];
int rem[N];
struct query{
int l,r,val,id;
}q[N];
int cmp(query x,query y){
if(x.l/sq!=y.l/sq) return x.l/sq<y.l/sq;
else return x.r<y.r;
}
tree<pair<int,int>,null_type,less<pair<int,int> >,rb_tree_tag,tree_order_statistics_node_update>tr;
int cnt=0;
void add(int pos){
tr.insert(make_pair(a[pos],++cnt));
rem[pos]=cnt;
}
void del( int pos){
tr.erase(make_pair(a[pos],rem[pos]));
}
void solve(){
tr.clear();
int n,m;
cin>>n>>m;
for( int i=0;i<n;i++){
cin>>a[i];
}
for( int i=0;i<m;i++){
cin>>q[i].l>>q[i].r>>q[i].val;
q[i].id=i;
}
sort(q,q+m,cmp);
cnt=0;
for( int i=0,pl=1,pr=0;i<m;i++){
int id=q[i].id,l=q[i].l,r=q[i].r;
while(pr>r) del(pr--);
while(pr<r) add(++pr);
while(pl>l) add(--pl);
while(pl<l) del(pl++);
ans[id]=tr.order_of_key(make_pair(q[i].val,inf));
}
for( int i=0;i<m;i++) printf("%d\n",ans[i]);
}
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
int t;
cin>>t;
for( int i=1;i<=t;i++){
printf("Case %d:\n",t);
solve();
}
return 0;
}