您的位置:首页 > 其它

[bzoj3333][排队计划][树状数组+线段树]

2015-09-05 19:00 309 查看

Description



Input



Output



Sample Input

6 2

160 163 164 161 167 160

2

3

Sample Output

6

3

1

HINT



题解:首先用树状数组求出每个数到结尾的子序列有多少逆序对.加起来即是第一问答案.
对于第二问我们发现答案只会变少.而且每次减少的都是选出来的那些数往后的逆序对数.
所以我们再对所有数建一棵线段树.每次查一下选出数往后的最小值.减去对应的逆序对数,在把这个数赋成正无穷.直到查出来的数等于你选的那个数.
#include<iostream>
#include<cstdio>
#include<algorithm> 
#define N 500010
#define inf 1000000001
using namespace std;
int n,m,b
,t,x;
bool ff
;
struct use2{int p,v;}tree[N*4],temp;
long long ans,c
,f
;
struct use{int v,p;}a
;
bool cmp(use a,use b){if (a.v==b.v) return a.p<b.p;return a.v<b.v;}
int lowbit(int x){return x&(-x);}
void modify(int x){while (x<=n){c[x]+=1;x+=lowbit(x);}}
long long sum(int x){int s(0);while (x>0){s+=c[x];x-=lowbit(x);}return s;}
void insert(int k,int l,int r,int x,int w)
{
  int mid=(l+r)>>1;
  if (l==r&&l==x){tree[k].v=w;tree[k].p=x;return;}if (x<=mid) insert(k<<1,l,mid,x,w);
  else insert(k<<1|1,mid+1,r,x,w);
  if (tree[k<<1].v<tree[k<<1|1].v){tree[k].v=tree[k<<1].v;tree[k].p=tree[k<<1].p;}
  else {tree[k].v=tree[k<<1|1].v;tree[k].p=tree[k<<1|1].p;} 
}
use2 query(int k,int l,int r,int ll,int rr)
{
    use2 a,b;a.v=inf;b.v=inf;
    int mid=(l+r)>>1;
    if (ll<=l&&r<=rr){return tree[k];}
    if (ll<=mid) a=query(k<<1,l,mid,ll,rr);
    if (mid<r) b=query(k<<1|1,mid+1,r,ll,rr);
    if (a.v<b.v) return a;return b; 
}
inline int read()  
{  
    int x=0,f=1;char ch=getchar();  
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}  
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}  
    return x*f;  
} 
int main()
{
  n=read();m=read();
  for (int i=1;i<=n;i++) {a[i].v=read();a[i].p=i;b[i]=a[i].v;}
  sort(a+1,a+n+1,cmp);
  for (int i=1;i<=n;i++){f[a[i].p]=sum(n)-sum(a[i].p);modify(a[i].p);}
  for (int i=1;i<=n;i++)ans+=f[i];printf("%lld\n",ans);
  for (int i=1;i<=n;i++) insert(1,1,n,i,b[i]);
  for (int i=1;i<=m;i++)
   {
    x=read();
    if (!ff[x])
    {
        temp=query(1,1,n,x,n);
        while (temp.p!=x)
        {
          if (!ff[temp.p])ans-=f[temp.p];ff[temp.p]=true;
          insert(1,1,n,temp.p,inf);
          temp=query(1,1,n,x,n);
        }ff[temp.p]=true;
        ans-=f[temp.p];
    }
    printf("%lld\n",ans);
   }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: