• P1966 火柴排队


    让A,b序列中大小排名相对应即可

    若A中第j大的位于i,则应该b中第j大位于i

    证明:假如a1<a2,b1<b2

    则排列方式有 a1,a2,b1,b2或 a1,a2,b2,b1那么

    对于这两种情况上,平方并做差,即可得以上结论

    然而大问题是这样离散化后怎么搞出交换几次呢
    离散化后
    (c_{a_i})=(b_i),然后若我们最后拍完序
    定然(c_i)=i

    也就是记录了相同排名的值得对应关系
    结果是要让他们一一对应的
    也就是上面的
    拍完序后,然后就是相同位置对应了
    其实也就是记录了A中第i大的元素的位置和b中的对应位置

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    int tree[100001];
    struct num{
    	int v;
    	int p;
    }a[100001],b[100001];
    int n;
    const int mod = 99999997;
    int a1[100001];
    int b1[100001];
    int c[100001];
    int q[100001];
    bool cmp(num x,num y){
    	return x.v<y.v;
    }
    int lowbit(int x){
    	return x&-x;
    }
    void up(int x,int y){
    	while(x<=n){
    		tree[x]+=y;
    		tree[x]%=mod;
    		x+=lowbit(x);
    	} 
    } 
    int find(int x){
    	int ans=0;
    	while(x>=1){
    		ans+=tree[x];
    		ans%=mod;
    		x-=lowbit(x);
    	}
    	return ans;
    }
    int ans;
    bool cmp1(const int &x,const int &y){
    	return q[x]>q[y];
    }
    int main (){
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i){
    		scanf("%d",&a[i].v);
    		a[i].p=i;
    	}
    	for(int i=1;i<=n;++i){
    		scanf("%d",&b[i].v);
    		b[i].p=i;
    	}
    	sort(a+1,a+1+n,cmp);
    	sort(b+1,b+1+n,cmp);
    	for(int i=1;i<=n;++i){
    		q[a[i].p]=b[i].p;
    	}
    	for(int i=n;i>=1;--i){
    		up(q[i],1);
    		ans+=find(q[i]-1)%mod;
    		
    		ans%=mod;
    	}
    	cout<<(ans%mod+mod)%mod;
    	return 0;
    }
    
  • 相关阅读:
    页面检测网络外网连接- 网页基础模块(JavaScript)
    sql server替换字段中的某个字符
    关于Linux下 fork() 函数的总结
    郁闷的一天
    关于 Linux 下的线程函数未定义问题
    英文书籍
    学会阅读外文资料
    内存池设计(五)
    内存池设计(四)
    内存池设计(三)
  • 原文地址:https://www.cnblogs.com/For-Miku/p/13567494.html
Copyright © 2020-2023  润新知