hdu 5196 DZY Loves Inversions(线段树+树状数组+离线+two points)
来源:互联网 发布:java 字符串的分割 编辑:程序博客网 时间:2024/06/04 01:04
先离散化数组,定义了两个数组r[i]和r1[i],r[i]表示min{ j( j~i的逆序数对小于等于k)},r1[i]表示min{ j( j~i的逆序数对小于k)},然后离线处理查询,接着从1开始遍历每个位置,假如遍历到i如果r[i]<r1[i] 那就在r[i]~r1[i]-1每个位置加1(lazy),加完之后遍历以i结尾的查询(也就是l~r 其中r=i)那么这个查询的值就是l~r每个位置加的数之和.
有个超级大坑点就是1个数的逆序数对也为0,所以k=0的时候一定要考虑到这点(wa了一上午)。
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<vector>using namespace std;const int maxn=100005;typedef long long LL;int bit[maxn];struct ppi{ int id; int to;}pp1;vector<ppi >g[maxn];int low(int p){return p&(-p);}void merg(int p,int n,int k){ while(p<=n){ bit[p]+=k; p=p+low(p); }}int sum(int p){ int s=0; while(p>0){ s+=bit[p]; p=p-low(p); } return s;}int r[maxn],r1[maxn];int a[maxn],b[maxn];LL c[maxn];struct pi{ int le; int ri; int lazy; LL sum;}pp[maxn<<2];void build(int tot,int l,int r){ pp[tot].le=l; pp[tot].ri=r; pp[tot].sum=0; pp[tot].lazy=0; if(l==r) return ; build(2*tot,l,(l+r)/2); build(2*tot+1,(l+r)/2+1,r);}void merg1(int tot,int l,int r,int p){ if(pp[tot].le>=l&&pp[tot].ri<=r){ pp[tot].lazy+=p; return ; } int mid=(pp[tot].le+pp[tot].ri)/2; if(l<=mid) merg1(2*tot,l,r,p); if(r>mid) merg1(2*tot+1,l,r,p); pp[tot].sum+=(min(r,pp[tot].ri)-max(l,pp[tot].le)+1)*p;}LL sum(int tot,int l,int r){ if(pp[tot].le>=l&&pp[tot].ri<=r){ return (LL)(pp[tot].ri-pp[tot].le+1)*(pp[tot].lazy)+pp[tot].sum; } LL s=0; int mid=(pp[tot].le+pp[tot].ri)/2; s=(LL)(min(r,pp[tot].ri)-max(l,pp[tot].le)+1)*pp[tot].lazy; if(l<=mid) s+=sum(2*tot,l,r); if(r>mid) s+=sum(2*tot+1,l,r); return s;}int main(){ int i,j,n,m; LL k,k1; while(scanf("%d%d%I64d",&n,&m,&k)!=EOF){ memset(bit,0,sizeof(bit)); for(i=1;i<=n;i++){ scanf("%d",&b[i]); a[i]=b[i]; } sort(b+1,b+1+n); for(i=1;i<=n;i++){ a[i]=(int)(lower_bound(b+1,b+1+n,a[i])-b); } j=1; k1=0; r[1]=1; merg(a[1],n,1); for(i=2;i<=n;i++){ while(j<=i){ int p=sum(n)-sum(a[i]); if(k<p+k1){ int w=sum(a[j]-1); k1-=w; merg(a[j],n,-1); j++; } else{ k1=p+k1; break; } } merg(a[i],n,1); r[i]=j; if(j>i){ r[i]=i; } } if(k==0){ for(j=1;j<=n;j++){ r1[j]=j+1; } } else{ j=1; k1=0; r1[1]=1; memset(bit,0,sizeof(bit)); merg(a[1],n,1); for(i=2;i<=n;i++){ while(j<=i){ int p=sum(n)-sum(a[i]); if(k<=p+k1){ int w=sum(a[j]-1); k1-=w; merg(a[j],n,-1); j++; } else{ k1=p+k1; break; } } merg(a[i],n,1); r1[i]=j; } } build(1,1,n); for(i=1;i<=n;i++) g[i].clear(); for(i=0;i<m;i++){ int a,b; scanf("%d%d",&a,&b); pp1.id=i; pp1.to=a; g[b].push_back(pp1); } for(i=1;i<=n;i++){ if(r1[i]-1>=r[i]){ merg1(1,r[i],r1[i]-1,1); } int p=(int)g[i].size(); for(j=0;j<p;j++){ c[g[i][j].id]=sum(1,g[i][j].to,i); } } for(i=0;i<m;i++) printf("%I64d\n",c[i]); }}
0 0
- hdu 5196 DZY Loves Inversions(线段树+树状数组+离线+two points)
- HDU 5196 DZY Loves Inversions(离线+线段树)
- HDU 5196 DZY Loves Inversions(树状数组,二分)
- hdu 5196 DZY Loves Inversions(树状数组,二分法,逆序数)
- hdu 5196 DZY Loves Inversions && BestCoder Round #35
- HDU 5195 DZY Loves Topological Sorting(线段树)
- hdu 5195 DZY Loves Topological Sorting(线段树)
- [HDU 5649] DZY Loves Sorting (线段树+二分)
- HDU 5649 DZY Loves Sorting (二分 + 线段树)
- HDU 4417 Super Mario(线段树||树状数组+离线操作 之树状数组篇)
- HDU 4417 Super Mario(线段树||树状数组+离线操作 之线段树篇)
- HDU 5195 DZY Loves Topological Sorting (拓扑排序+线段树)
- hdu 5649 DZY Loves Sorting(二分+线段树)
- HDU 5649 DZY Loves Sorting(线段树+二分)
- POJ 2464 Brownie Points II(树状数组||线段树)
- HDU 5195 DZY Loves Topological Sorting(线段树单点更新)
- 【HDU】5195-DZY Loves Topological Sorting(拓扑 + 线段树 + 贪心)
- HDU 4417 Super Mario(离线线段树or树状数组)
- Spring+Spring MVC+JDBCTemplate实现简单的用户管理功能
- 第三周项目二 三角形(2)
- Java Atomic 12大类实例讲解和原理分解
- Oracle 11gR2上遇到blocking txn id for DDL等待事件
- Android两级导航菜单栏的实现--FragmentTabHost结合ViewPager与Android 开源项目PagerSlidingTabStrip
- hdu 5196 DZY Loves Inversions(线段树+树状数组+离线+two points)
- 关于 android 和 php 开发实践
- 典型的Top K算法
- C++的cout高阶格式化操作
- 第四周项目二
- Android中的Selector的用法
- 安全技术
- oracle的购买价格研究(三)-附x86价格
- 为什么好的博客越来越少?