【题目地址】 点击打开链接
【分析】
仔细分析题目后,我们可以简化模型:
给出一个1~N的全排列,并标记一些数要保留。求每个不保留的数左边第一个比自己小的要保留的数,以及右边第一个比自己小的要保留的数。
这样用STL中的set就可以轻松解决了
【代码】
/*************************
ID:Ciocio
LANG:C++
DATE:2014-1-31
TASK:George and Cards
*************************/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
using namespace std;
#define MAXN 1000000
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define rrep(i,b,a) for(int i=b;i>=a;--i)
#define pii pair<int,int>
#define x first
#define y second
#define LL long long
#define lowbit(x) ((x)&(-(x)))
int N,K;
int bit[MAXN+10];
bool cannotmove[MAXN+10];
pii A[MAXN+10];
void _init(){
scanf("%d%d",&N,&K);
rep(i,1,N){
scanf("%d",&A[i].x);
A[i].y=i;
}
sort(A+1,A+N+1);
rep(i,1,K){
int b;
scanf("%d",&b);
cannotmove[b]=true;
}
}
void _solve(){
LL ans=0,l,r;
set <int> Set;
set <int>::iterator it;
Set.insert(0);
Set.insert(N+1);
rep(i,1,N){
if(cannotmove[A[i].x]){
Set.insert(A[i].y);
}
else{
Set.insert(A[i].y);
it=Set.find(A[i].y);
it--;
l=(*it)+1;
it++;
it++;
r=(*it)-1;
ans+=r+1-l;
for(;r;r-=lowbit(r)) ans+=bit[r];
for(l--;l;l-=lowbit(l)) ans-=bit[l];
for(int j=A[i].y;j<=N;j+=lowbit(j)) bit[j]--;
Set.erase(A[i].y);
}
}
cout<<ans<<endl;
}
int main(){
_init();
_solve();
return 0;
}