• BZOJ3289 Mato的文件管理


    好友JZYshuraK推荐的莫队题目。

    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]区间的文件。
    n,q <= 50000

    Output

    q行,每行一个正整数,表示Mato这天需要交换的次数。

    Sample Input

    4

    1 4 2 3

    2

    1 2

    2 4

    Sample Output

    0

    2

    //样例解释:第一天,Mato不需要交换

    第二天,Mato可以把2号交换2次移到最后。
     
    此题就是动态求逆序对。用莫队的思想移动左右端点,之后考虑逆序对改变的个数。用树状数组再次求解。
    还有就是注意离散化a[i],写题时忘了。
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define N 100001
    #define mod 240
    int n,Q;
    int a[N];
    int c[N];
    int dist[N];
    struct Query
    {
    	int id,x,y,daan,blob;
    }query[N];
    bool cmp(const Query &a,const Query &b)
    {
    	if(a.blob!=b.blob)
    		return a.blob<b.blob;
    	else
    		return a.y<b.y;
    }
    bool cmp2(const Query &a,const Query &b){return a.id<b.id;}
    int lowbit(int x){return x&-x;}
    void add(int x,int delta)
    {
    	while(x<=n)
    	{
    		c[x]+=delta;
    		x+=lowbit(x);
    	}
    }
    int find(int x)
    {
    	int ans=0;
    	while(x)
    	{
    		ans+=c[x];
    		x-=lowbit(x);
    	}
    	return ans;
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d",&a[i]);
    		dist[i]=a[i];
    	}
    	sort(dist+1,dist+n+1);
    	for(int i=1;i<=n;i++)
    		a[i]=lower_bound(dist+1,dist+n+1,a[i])-dist;
    	scanf("%d",&Q);
    	for(int i=1;i<=Q;i++)
    	{
    		scanf("%d%d",&query[i].x,&query[i].y);
    		if(query[i].x%mod==0)
    			query[i].blob=query[i].x/mod;
    		else
    			query[i].blob=query[i].x/mod+1;
    		query[i].id=i;
    	}
    	sort(query+1,query+Q+1,cmp);
    	int l=1,r=0;
    	int ans=0;
    	for(int i=1;i<=Q;i++)
    	{
    		while(l<query[i].x)
    			add(a[l],-1),ans-=find(a[l]-1),l++;
    		while(l>query[i].x)
    			add(a[--l],1),ans+=find(a[l]-1);
    		while(r<query[i].y)
    			add(a[++r],1),ans+=r-l+1-find(a[r]);
    		while(r>query[i].y)
    			add(a[r],-1),ans-=r-l-find(a[r]),r--;
    		query[i].daan=ans;
    	}
    	sort(query+1,query+Q+1,cmp2);
    	for(int i=1;i<=Q;i++)
    		printf("%d\n",query[i].daan);
    	return 0;
    }
    

      

  • 相关阅读:
    github克隆镜像
    python2安装pip(get-pip.py)和pip更新源
    GitHack使用—create_unverified_context报错
    XCTF:shrine(Flask模块注入)
    开机自启动(C#)
    操作xml(C#)
    隐藏到托盘(C#)
    火狐浏览器下请求两次(C#)
    Nancy学习笔记
    jquery纵向抽屉式导航栏
  • 原文地址:https://www.cnblogs.com/342zhuyongqi/p/9803790.html
Copyright © 2020-2023  润新知