[bzoj3333][排队计划][树状数组+线段树]
2015-09-05 19:00
309 查看
Description
Input
Output
Sample Input
6 2160 163 164 161 167 160
2
3
Sample Output
63
1
HINT
题解:首先用树状数组求出每个数到结尾的子序列有多少逆序对.加起来即是第一问答案.
对于第二问我们发现答案只会变少.而且每次减少的都是选出来的那些数往后的逆序对数.
所以我们再对所有数建一棵线段树.每次查一下选出数往后的最小值.减去对应的逆序对数,在把这个数赋成正无穷.直到查出来的数等于你选的那个数.
#include<iostream> #include<cstdio> #include<algorithm> #define N 500010 #define inf 1000000001 using namespace std; int n,m,b ,t,x; bool ff ; struct use2{int p,v;}tree[N*4],temp; long long ans,c ,f ; struct use{int v,p;}a ; bool cmp(use a,use b){if (a.v==b.v) return a.p<b.p;return a.v<b.v;} int lowbit(int x){return x&(-x);} void modify(int x){while (x<=n){c[x]+=1;x+=lowbit(x);}} long long sum(int x){int s(0);while (x>0){s+=c[x];x-=lowbit(x);}return s;} void insert(int k,int l,int r,int x,int w) { int mid=(l+r)>>1; if (l==r&&l==x){tree[k].v=w;tree[k].p=x;return;}if (x<=mid) insert(k<<1,l,mid,x,w); else insert(k<<1|1,mid+1,r,x,w); if (tree[k<<1].v<tree[k<<1|1].v){tree[k].v=tree[k<<1].v;tree[k].p=tree[k<<1].p;} else {tree[k].v=tree[k<<1|1].v;tree[k].p=tree[k<<1|1].p;} } use2 query(int k,int l,int r,int ll,int rr) { use2 a,b;a.v=inf;b.v=inf; int mid=(l+r)>>1; if (ll<=l&&r<=rr){return tree[k];} if (ll<=mid) a=query(k<<1,l,mid,ll,rr); if (mid<r) b=query(k<<1|1,mid+1,r,ll,rr); if (a.v<b.v) return a;return b; } inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int main() { n=read();m=read(); for (int i=1;i<=n;i++) {a[i].v=read();a[i].p=i;b[i]=a[i].v;} sort(a+1,a+n+1,cmp); for (int i=1;i<=n;i++){f[a[i].p]=sum(n)-sum(a[i].p);modify(a[i].p);} for (int i=1;i<=n;i++)ans+=f[i];printf("%lld\n",ans); for (int i=1;i<=n;i++) insert(1,1,n,i,b[i]); for (int i=1;i<=m;i++) { x=read(); if (!ff[x]) { temp=query(1,1,n,x,n); while (temp.p!=x) { if (!ff[temp.p])ans-=f[temp.p];ff[temp.p]=true; insert(1,1,n,temp.p,inf); temp=query(1,1,n,x,n); }ff[temp.p]=true; ans-=f[temp.p]; } printf("%lld\n",ans); } }
相关文章推荐
- MFC对话框程序中的OnCreate和OnInitDialog函数
- nginx日志切割
- Android五分钟让你集成底部菜单栏(fragment或者fragment+viewpager)
- Linux根目录中个目录的含义
- nginx配置ssl双向验证 nginx https ssl证书配置
- 重载与重写
- 腾讯笔试题--删除set与vector中QQ号为奇数的号码
- hdu 4417 Super Mario(查找区间不大于h的数有多少个)(线段树+二分查找,划分树+二分查找)
- 可能是ThinkPHP导航高亮显示当前页面的最简便的方法(不服来辩哈哈)
- mycncart1.1.0.0 发布
- I/O Stream <傻瓜机器人对话>
- mycncart1.1.0.0 发布
- IIS发布常见错误-HTTP 错误 404.0 - Not-Found
- 用gdb调试core dump文件
- Linux常用帮助命令man,help,info
- 固化分组
- 【JAVASCRIPT】React学习-JSX 语法
- linux任务计划
- Java异常以及处理原则
- iOS的网络基础