Codefoeces 387E-George and Cards greedy + line segment tree
First, you must know that the minimum value is used to achieve the optimum, because the minimum value does not provide any extra points for others, but may only reduce the extra points.
The order of card deletion is determined, and the rest is to determine the Left and Right endpoints of each segment.
Pos [I] indicates the position of the digit I in the initial sequence.
First, enumerate I (I = 1-> n). If you do not need to delete it, put pos [I] into the set In S, if you do not need to delete it, search for the upper and lower bounds in S.
The total time complexity is o (n-k) * log (k )).
#include #include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#pragma comment(linker,"/STACK:1024000000");#define EPS (1e-6)#define LL long long#define ULL unsigned long long#define INF 0x3f3f3f3f#define Mod 1000000007#define mod 1000000007/** I/O Accelerator Interface .. **/#define g (c=getchar())#define d isdigit(g)#define p x=x*10+c-'0'#define n x=x*10+'0'-c#define pp l/=10,p#define nn l/=10,ntemplate
inline T& RD(T &x){ char c; while(!d); x=c-'0'; while(d)p; return x;}template
inline T& RDD(T &x){ char c; while(g,c!='-'&&!isdigit(c)); if (c=='-') { x='0'-g; while(d)n; } else { x=c-'0'; while(d)p; } return x;}inline double& RF(double &x) //scanf("%lf", &x);{ char c; while(g,c!='-'&&c!='.'&&!isdigit(c)); if(c=='-')if(g=='.') { x=0; double l=1; while(d)nn; x*=l; } else { x='0'-c; while(d)n; if(c=='.') { double l=1; while(d)nn; x*=l; } } else if(c=='.') { x=0; double l=1; while(d)pp; x*=l; } else { x=c-'0'; while(d)p; if(c=='.') { double l=1; while(d)pp; x*=l; } } return x;}#undef nn#undef pp#undef n#undef p#undef d#undef gusing namespace std;int num[1000010];int pos[1000010];bool ap[1000010];int st[4001000];set
s;int Init(int site,int l,int r){ if(l == r) return st[site] = 1; int mid = (l+r)>>1; return st[site] = Init(site<<1,l,mid) + Init(site<<1|1,mid+1,r);}int Query(int site,int L,int R,int l,int r){ if(L == l && R == r) return st[site]; int mid = (L+R)>>1; if(r <= mid) return Query(site<<1,L,mid,l,r); if(mid < l) return Query(site<<1|1,mid+1,R,l,r); return Query(site<<1,L,mid,l,mid) + Query(site<<1|1,mid+1,R,mid+1,r);}void Update(int site,int l,int r,int x){ if(l == r) { st[site] = 0; return ; } int mid = (l+r)>>1; if(x <= mid) Update(site<<1,l,mid,x); else Update(site<<1|1,mid+1,r,x); st[site] = st[site<<1] + st[site<<1|1];}int main(){ int n,k,i,j,x; scanf("%d %d",&n,&k); for(i = 1;i <= n; ++i) scanf("%d",&num[i]),pos[num[i]] = i; memset(ap,false,sizeof(ap)); for(i = 1;i <= k; ++i) scanf("%d",&x),ap[x] = true; set
::iterator it; LL sum = 0; Init(1,1,n); s.insert(n+1); s.insert(0); for(i = 1;i <= n; ++i) { if(ap[i]) { s.insert(pos[i]); continue; } it = s.upper_bound(pos[i]); int r = *it-1; int l = *(--it)+1; sum += Query(1,1,n,l,r); Update(1,1,n,pos[i]); } cout<