hdu 5196 DZY Loves Inversions && BestCoder Round #35
来源:互联网 发布:手机淘宝链接生成器 编辑:程序博客网 时间:2024/05/22 10:38
问题描述
DZY有一个序列a ,一共由n 个正整数组成,下标为1 到n 。我们定义第i 个数为ai 。DZY每次给定一个数对(l,r )(l≤r) ,他想计算有多少个数对(i,j ),满足l≤i≤j≤r ,且序列b=aiai+1⋯aj 有恰好k 个逆序对。而且,DZY会询问你q 次噢。
题解:
1.考虑如何计算一个区间中有多少个子区间的逆序对数小于等于K 。这样做两遍就能算出恰好等于K 的了。
2.对于i(1≤i≤n) ,fi表示[i,fi]逆序对数小于等于K ,且fi的值最大。显然fi单调不降,我们可
以通过用两个指针扫一遍,利用树状数组计算出f数组。
3.因为ai很大,但是只有1e5个,所以可以进行压缩映射成至多1 -- 1e5,才可以用树状数组维护逆序对数
4.询问l,r时,可以二分找到最大的f[i] <= r,维护一个前缀和
s = (f[l] - l + 1) + .... + (f[l + i] - l - i + 1)表示这些区间所能组成的最大子区间数
5.对于[i + 1,r],f[i + 1]肯定大于r,所以对于区间[i + 1,r],[i + 2,r]....[r,r],维护另一个前缀和
s1 = (r - i - 1 + 1) + ....... + (r - r + 1)表示这些区间所能组成的最大子区间数
总结:
1.看了bestcoder的前两点提醒才想到的,感觉又是一个运用前缀和和单调性思想的题目
2.debug代码的时候还算满意,没有死扣瞎提交,以后坚持,首先争取不犯设计上的错误,然后就要平静的查错
#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>using namespace std;typedef long long LL;#define MAXN 100005#define lowbit(i) (i & -i)int num[MAXN],bit[MAXN],n,q;LL fk1[MAXN],fk2[MAXN],s1[MAXN],s2[MAXN],k;struct Node{ int v,id; bool operator < (const Node & c)const{ return v < c.v; }}node[MAXN];int sum(int i){ int total = 0; for(;i;i -= lowbit(i)) total += bit[i]; return total;}void modify(int i,int key){ for(;i <= n;i += lowbit(i)) bit[i] += key;}void findf(LL k,LL * s,LL * ss){ LL cur = 0; memset(bit,0,sizeof(bit)); for(int i = 1,j = 0;i <= n;i++) { while(j <= n && cur <= k) { if(++j > n)break; cur += (j - i) - sum(num[j]); modify(num[j],1); } cur -= sum(num[i] - 1); modify(num[i],-1); s[i] = j - 1; ss[i] = ss[i - 1] + j - i; }}LL query(int l,int r){ int ind = upper_bound(fk1 + l,fk1 + r + 1,r) - fk1 - 1; LL cur = r - ind; LL ans1 = (cur + 1) * cur / 2 + s1[ind] - s1[l - 1]; if(!k)return ans1; ind = upper_bound(fk2 + l,fk2 + r + 1,r) - fk2 - 1; cur = r - ind; LL ans2 = (cur + 1) * cur / 2 + s2[ind] - s2[l - 1]; return ans1 - ans2;}void solve(){ findf(k,fk1,s1); if(k)findf(k - 1,fk2,s2); int l,r; for(int i = 0;i < q;i++) { scanf("%d%d",&l,&r); LL ans = query(l,r); printf("%I64d\n",ans); }}int main(){ while(~scanf("%d%d%I64d",&n,&q,&k)) { for(int i = 1;i <= n;i++) { scanf("%d",&num[i]); node[i].v = num[i]; node[i].id = i; } sort(node + 1,node + n + 1); num[node[1].id] = 1; for(int i = 2;i <= n;i++) if(node[i].v == node[i - 1].v) num[node[i].id] = num[node[i - 1].id]; else num[node[i].id] = num[node[i - 1].id] + 1; solve(); }}
0 0
- hdu 5196 DZY Loves Inversions && BestCoder Round #35
- hdu 5195 DZY Loves Topological Sorting && BestCoder Round #35
- HDU-5194-DZY Loves Balls(BestCoder Round # 35 )
- HDU 5196 DZY Loves Inversions(树状数组,二分)
- HDU 5196 DZY Loves Inversions(离线+线段树)
- BestCoder Round #35(DZY Loves Balls-暴力dp)
- BestCoder Round #35(DZY Loves Topological Sorting-堆+贪心)
- hdu 5196 DZY Loves Inversions(线段树+树状数组+离线+two points)
- hdu 5196 DZY Loves Inversions(树状数组,二分法,逆序数)
- BestCoder Round #76 (div.2) DZY Loves Balls
- BestCoder Round #76 (div.2)-DZY Loves Partition(模拟)
- 【BestCoder Round #76 (div.2)】DZY Loves Partition(数学分析)
- hdu5196 DZY Loves Inversions 思路,计数
- hdu DZY Loves Balls
- hdu 5228 ZCC loves straight flush && BestCoder Round #41 1001
- hdu 5229 ZCC loves strings && BestCoder Round #41 1002
- hdu 5229 ZCC loves strings(Bestcoder Round #41)
- hdu 5230 ZCC loves hacking(BestCoder Round #41)
- 第四周项目1-三角形类的构造函数-带参数构造函数
- (1.1.21)继承和组合的区别
- poj 2250 Compromise(裸LCS DP)
- 使用selector来修改安卓自带组件的样式
- MySQL5.5卸载
- hdu 5196 DZY Loves Inversions && BestCoder Round #35
- 第五周阅读程序五
- centos Linux 分区
- Vim命令
- 扩展欧几里德算法
- Linux设备驱动开发环境的搭建
- Blackhat上没有讲的SAP手机安全如何黑掉世界500强CEO手机
- java基础知识2
- 第一次ACM,值得纪念的回忆