bzoj3289 Mato的文件管理
Posted AaronPolaris
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3289 Mato的文件管理相关的知识,希望对你有一定的参考价值。
3289: Mato的文件管理
Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 1759 Solved: 755
[Submit][Status][Discuss]
Description
Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号。为了防止他人偷拷,这些资料都是加密过的,只能用Mato自己写的程序才能访问。Mato每天随机选一个区间[l,r],他今天就看编号在此区间内的这些资料。Mato有一个习惯,他总是从文件大小从小到大看资料。他先把要看的文件按编号顺序依次拷贝出来,再用他写的排序程序给文件大小排序。排序程序可以在1单位时间内交换2个相邻的文件(因为加密需要,不能随机访问)。Mato想要使文件交换次数最小,你能告诉他每天需要交换多少次吗?
Input
第一行一个正整数n,表示Mato的资料份数。
第二行由空格隔开的n个正整数,第i个表示编号为i的资料的大小。
第三行一个正整数q,表示Mato会看几天资料。
之后q行每行两个正整数l、r,表示Mato这天看[l,r]区间的文件。
Output
q行,每行一个正整数,表示Mato这天需要交换的次数。
Sample Input
4
1 4 2 3
2
1 2
2 4
1 4 2 3
2
1 2
2 4
Sample Output
0
2
2
HINT
Hint
n,q <= 50000
样例解释:第一天,Mato不需要交换
第二天,Mato可以把2号交换2次移到最后。
Source
莫队算法+树状数组
莫队算法的主要问题在于边界移动的时候答案如何改变,这里用树状数组维护就好了。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> #include<map> #define F(i,j,n) for(int i=j;i<=n;i++) #define D(i,j,n) for(int i=j;i>=n;i--) #define ll long long #define maxn 50005 using namespace std; int n,m,l,r,tot,block; int a[maxn],b[maxn],s[maxn]; ll now,ans[maxn]; struct data{int l,r,num,id;}p[maxn]; map<int,int> mp; 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; } inline bool cmp(data a,data b) { return a.num==b.num?a.r<b.r:a.num<b.num; } inline void add(int x,int y) { for(;x<=tot;x+=(x&(-x))) s[x]+=y; } inline int query(int x) { int ret=0; for(;x;x-=(x&(-x))) ret+=s[x]; return ret; } int main() { n=read(); block=(int)sqrt(n); F(i,1,n) b[i]=a[i]=read(); sort(b+1,b+n+1); F(i,1,n) if (i==1||b[i]!=b[i-1]) mp[b[i]]=++tot; F(i,1,n) a[i]=mp[a[i]]; m=read(); F(i,1,m) p[i].l=read(),p[i].r=read(),p[i].num=(p[i].l-1)/block+1,p[i].id=i; sort(p+1,p+m+1,cmp); l=1;r=0; F(i,1,m) { if (i==1||p[i].num!=p[i-1].num) r=(p[i].num-1)*block,l=r+1,memset(s,0,sizeof(s)),now=0; while (r<p[i].r) r++,add(a[r],1),now+=r-l+1-query(a[r]); while (l<p[i].l) add(a[l],-1),now-=query(a[l]-1),l++; while (l>p[i].l) l--,add(a[l],1),now+=query(a[l]-1); ans[p[i].id]=now; } F(i,1,m) printf("%lld\n",ans[i]); return 0; }
以上是关于bzoj3289 Mato的文件管理的主要内容,如果未能解决你的问题,请参考以下文章