洛谷P1908 逆序对

题目描述

猫猫 TOM 和小老鼠 JERRY 最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。

最近,TOM 老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中 ai>aj,且 i

Update:数据已加强。

输入格式

第一行,一个数n,表示序列中有 n个数。

第二行 n 个数,表示给定的序列。序列中每个数字不超过 10^9。

输出格式

输出序列中逆序对的数目。

输入输出样例

输入 #1 复制
6
5 4 2 6 3 1
输出 #1 复制
11

题解

题解是https://www.luogu.com.cn/blog/cpp/solution-p1908大佬的版本
因为自己的是java所以保存一下以后来翻
侵删!!!!

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;


public class Main{
	
	static int n;
	static long ans;
	static int[]a=new int [500005];
	static int[]c=new int [500005];
	
	public static void run(int l,int r){
		if(l==r)
			return;
		int mid=(l+r)/2,i=l,j=mid+1,k=l;
		run(l, mid);
		run(mid+1, r);
		
		while(i<=mid&&j<=r){
			
			if (a[i]<=a[j]) {
				c[k++]=a[i++];
			}else {
				c[k++]=a[j++];
				ans=ans+mid-i+1;
			}
		}
		while(i<=mid)
			c[k++]=a[i++];
		while(j<=r)
			c[k++]=a[j++];
		for(int m=l;m<=r;m++)
			a[m]=c[m];
	}
	public static void main(String[] args){
		InputReader in=new InputReader(System.in);
		n=in.nextInt();
		for(int i=1;i<=n;i++)
			a[i]=in.nextInt();
		run(1, n);
		System.out.println(ans);
	}
	public static class InputReader{
		BufferedReader reader;
		StringTokenizer tokenizer;
		
		public InputReader(InputStream stream){
			reader=new BufferedReader(new InputStreamReader(System.in),32768);
			tokenizer=null;
		}
		public String next(){
			
			while (tokenizer==null||!tokenizer.hasMoreTokens()) {
				
				try {
					tokenizer=new StringTokenizer(reader.readLine());
				} catch (IOException e) {
					// TODO Auto-generated catch block
					throw new RuntimeException(e);
				}
				
			}
			return tokenizer.nextToken();
		}
		public int nextInt(){
			return Integer.parseInt(next());
		}
		public boolean ready() throws IOException{
			return reader.ready();
		}
	}
}

你可能感兴趣的:(洛谷P1908 逆序对)