[BZOJ3289]Mato的文件管理 Solution

题意:给一个序列,若干个询问,每次询问一个区间的逆序对个数。
考虑数据范围很小,就可以使用莫队,如何计算扩展的一个点的贡献?用树状数组维护即可。
c o d e : code: code:

#include <bits/stdc++.h>
#define int long long
#define regi register int
int n,q;
int a[51000];
int tmp[51000],cnt;
int pos[51000];
int ans[51000];
int s=0;
int c[51000];
int L,R;
std::map<int,int>Dis;
struct question{
   int l;
   int r;
   int id;
}ques[51000];
inline bool compare_for_l(question x,question y){
   if(pos[x.l]==pos[y.l]){
   	return x.r<y.r;
   }
   return pos[x.l]<pos[y.l];
}
inline void add(int x,int v){
   for(;x<=n;x+=x&-x)
     c[x]+=v;
}
inline int ask(int x){
   int S=0;
   for(;x;x-=x&-x)
     S+=c[x];
   return S;
}
main(){
 scanf("%lld",&n);
 for(regi i=1,blk=sqrt(n);i<=n;++i){
   scanf("%lld",&a[i]);
   tmp[i]=a[i];
   pos[i]=(i-1)/blk+1;
 }
 std::sort(tmp+1,tmp+n+1);
 for(regi i=1;i<=n;++i)
   if(tmp[i]!=tmp[i-1])
     Dis[tmp[i]]=++cnt;
 for(regi i=1;i<=n;++i)
   a[i]=Dis[a[i]];
 scanf("%lld",&q);
 for(regi i=1;i<=q;++i){
 	scanf("%lld%lld",&ques[i].l,&ques[i].r);
 	ques[i].id=i;
 }
 std::sort(ques+1,ques+q+1,compare_for_l);
 L=1;
 for(regi i=1;i<=q;++i){
 	while(L<ques[i].l){
 	  s-=ask(a[L]-1);
 	  add(a[L],-1);
 	  ++L;
 	}
   while(R>ques[i].r){
     add(a[R],-1);
     s-=R-L-ask(a[R]);
     --R;
   }
 	while(L>ques[i].l){
 		--L;
 		s+=ask(a[L]-1);
 		add(a[L],1);
 	}
   while(R<ques[i].r){
     ++R;
     s+=R-L-ask(a[R]);
     add(a[R],1);
   }
   ans[ques[i].id]=s;
 }
 for(regi i=1;i<=q;++i)
   printf("%lld\n",ans[i]);
   return 0;
}
/*
 考虑树状数组怎么维护 
 左端点往前:
     会增加一些数,考虑这些数产生的贡献,那就是后面比它小的数的个数,显然可以做到
   左端点往后:
     会减少一些数,考虑这些数产生的影响,还是后面比它小的数的个数。
   右端点往后:
     多了几个数, 这些数产生的贡献便是前面比它大的数的个数。
   右端点往前:
     那就是答案减去前面比他大的数的个数。 
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值