您的位置:首页 > 其它

hdu5196 DZY Loves Inversions 思路,计数

2015-10-06 14:45 337 查看
题意:一个数列,给出一些区间,计算这个区间有多少子区间逆序对数为k。

分析:直接计算k不好算,把问题转化为<=k的子区间数减去<k的子区间数。首先由两个指针可以求出每一个点的满足<=k或<k的最右边界。得到r1和r2数组。

   最后所求即为sum(min(r1i,r)-l+1) (i>=l&&i<=r),r数组单调递增,二分即可。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<ostream>
#include<istream>
#include<algorithm>
#include<queue>
#include<string>
#include<cmath>
#include<set>
#include<map>
#include<stack>
#include<vector>
#define fi first
#define se second
#define ll long long
#define pii pair<int,int>
#define inf (1<<30)
#define eps 1e-8
#define pb push_back
#define debug puts("=====")
using namespace std;
const int maxn=100005;
int n,q;
ll k;
int l,r;
int d[maxn];
int dis[maxn];
int r1[maxn],r2[maxn];
ll s1[maxn],s2[maxn];
int tree[maxn];
int lowbit(int x)
{
return x&-x;
}
int Sum(int a)
{
int sum=0;
while(a>0) {
sum+=tree[a];
a-=lowbit(a);
}
return sum;
}
void update(int x,int c)
{
while(x<=n) {
tree[x]+=c;
x+=lowbit(x);
}
}
void pre()
{
memset(tree,0,sizeof(tree));
int i=1,j=0;
ll sum=0;
while(i<=n) {
while(sum<=k && j<=n) {
j++;
if(j==n+1) break;
sum+=Sum(n)-Sum(d[j]);
update(d[j],1);
}
r1[i]=j-1;
update(d[i],-1);
sum-=Sum(d[i]-1);
i++;
}
memset(tree,0,sizeof(tree));
i=1,j=0,sum=0;
while(i<=n) {
while(sum<=k-1 && j<=n) {
j++;
if(j==n+1) break;
sum+=Sum(n)-Sum(d[j]);
update(d[j],1);
}
r2[i]=j-1;
update(d[i],-1);
sum-=Sum(d[i]-1);
i++;
}
s1[0]=s2[0]=0;
for(int i=1;i<=n;i++) {
s1[i]=s1[i-1]+r1[i];
s2[i]=s2[i-1]+r2[i];
}
}
int main()
{
while(~scanf("%d%d%I64d",&n,&q,&k)) {
for(int i=1;i<=n;i++) {
scanf("%d",&d[i]);
dis[i-1]=d[i];
}
sort(dis,dis+n);
int tot=unique(dis,dis+n)-dis;
for(int i=1;i<=n;i++) {
d[i]=lower_bound(dis,dis+tot,d[i])-dis+1;
}
pre();
ll ans;
while(q--) {
ans=0;
scanf("%d%d",&l,&r);
int kk=upper_bound(r1+l,r1+r+1,r)-r1;
kk--;
ans+=s1[kk]-s1[l-1];
ans+=(ll)(r-kk)*r;
if(k==0) {
ans+=(ll)(r-l+1)*(2-l-r)/2;
printf("%I64d\n",ans);
continue;
}
kk=upper_bound(r2+l,r2+r+1,r)-r2;
kk--;
ans-=s2[kk]-s2[l-1];
ans-=(ll)(r-kk)*r;
printf("%I64d\n",ans);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: