HDU 5273 Dylans loves sequence

8 篇文章 0 订阅

题意:

Dylans得到了NN个数a[1]...a[N]a[1]...a[N]。
有QQ个问题,每个问题形如(L,R)(L,R)
他需要求出L-RLR这些数中的逆序对个数。
更加正式地,他需要求出二元组(x,y)(x,y)的个数,使得L \leq x,y \leq RLx,yRx < yx<ya[x] > a[y]a[x]>a[y]

就是求一个区间逆序数的个数。N≤1000,Q≤100000,L≤R


第一想法就是直接树状数组解决这个问题,但是这道题BC估计是坑了一下大家,因为他m的值有点大,在里面嵌套查询逆序对的个数那么就会超时。实际上还是跟我们留了空间的,因为他的n只有1000.所以根本不需要用树状数组来找逆序数,只需要暴力求解就可以了。


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int n,m;
int a[1005];
int sum[1005][1005];
int cnt[1005][1005];
<pre name="code" class="cpp">//cnt[i][j]代表i对i到j的所有数产生的逆序数

//sum[i][j]代表i到j的所有逆序数

//1 4
//2 4
//3 4


int main(){ while(~scanf("%d%d",&n,&m)) { for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=0;i<=1000;i++) { for(int j=0;j<=1000;j++) { sum[i][j]=0; cnt[i][j]=0; } } for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { if(a[i]>a[j]) { cnt[i][j]=cnt[i][j-1]+1; } else { cnt[i][j]=cnt[i][j-1]; } } } for(int i=2;i<=n;i++) { int ans=0; for(int j=1;j<i;j++) { ans+=cnt[j][i]; } sum[1][i]=ans; } for(int i=2;i<=n;i++) { for(int j=i+1;j<=n;j++) { sum[i][j]=sum[i-1][j]-cnt[i-1][j]; } } for(int i=0;i<m;i++) { int u,v; scanf("%d%d",&u,&v); printf("%d\n",sum[u][v]); } }}
 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值