Gym 100463A Crossings 逆序对

Crossings

Time Limit: 20 Sec

Memory Limit: 256 MB

题目连接

http://codeforces.com/gym/100463

Description

Given a permutation P of {0, 1, ..., n − 1}, we define the crossing number of it as follows. Write the sequence 0, 1, 2, . . . , n − 1 from left to right above the sequence P(0), P(1), . . . , P(n − 1). Draw a straignt line from 0 in the top line to 0 in the bottom line, from 1 to 1, and so on. The crossing number of P is the number of pairs of lines that cross. For example, if n = 5 and P = [1, 3, 0, 2, 4], then the crossing number of P is 3, as shown in the figure below. !""""#""""""""""""&" In this problem a permutation will be specified by a tuple (n, a, b), where n is a prime and a and b are integers (1 ≤ a ≤ n − 1 and 0 ≤ b ≤ n − 1). We call this permutation Perm(n, a, b), and the ith element of it is a ∗ i + b mod n (with i in the range [0, n − 1]). So the example above is specified by Perm(5, 2, 1).

Input

There are several test cases in the input file. Each test case is specified by three space-separated numbers n, a, and b on a line. The prime n will be at most 1,000,000. The input is terminated with a line containing three zeros.

Output

For each case in the input print out the case number followed by the crossing number of the permutation. Follow the format in the example output.

Sample Input

5 2 1 19 12 7 0 0 0

Sample Output

Case 1: 3 Case 2: 77

HINT

题意

给你n个数,   第i-1个数等于(a*i+b)%n,问逆序对有多少

题解:

树状数组

代码

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <cstring>
 4 #include <ctime>
 5 #include <iostream>
 6 #include <algorithm>
 7 #include <set>
 8 #include <vector>
 9 #include <queue>
10 #include <map>
11 #include <stack>
12 #define MOD 1000000007
13 #define maxn 32001
14 using namespace std;
15 typedef __int64 ll;
16 inline ll read()
17 {
18     ll x=0,f=1;
19     char ch=getchar();
20     while(ch<‘0‘||ch>‘9‘)
21     {
22         if(ch==‘-‘)f=-1;
23         ch=getchar();
24     }
25     while(ch>=‘0‘&&ch<=‘9‘)
26     {
27         x=x*10+ch-‘0‘;
28         ch=getchar();
29     }
30     return x*f;
31 }
32 //*******************************************************************
33
34 struct ss
35 {
36     int v,index;
37 } in[1000005];
38 int c[1000005];
39 int a[1000005];
40 ll n;
41 bool cmp(ss s1,ss s2)
42 {
43     return s1.v<s2.v;
44 }
45 int lowbit(int x)
46 {
47     return x&(-x);
48 }
49 int getsum(int x)
50 {
51     int sum=0;
52     while(x>0)
53     {
54         sum+=c[x];
55         x-=lowbit(x);
56     }
57     return sum;
58 }
59 void update(int x,int value)
60 {
61     while(x<=n)
62     {
63         c[x]+=value;
64         x+=lowbit(x);
65     }
66 }
67
68 int main()
69 {
70     ll x,y;
71     int oo=1;
72     while(scanf("%lld%lld%lld",&n,&x,&y)!=EOF)
73     {
74         if(n==0&&x==0&&y==0)break;
75         memset(c,0,sizeof(c));
76         for(int i=0; i<n; i++)
77         {
78             a[i+1]=(x*i+y)%n+1;
79         }
80         ll ans=0;
81         for(int i=1; i<=n; i++)
82         {
83             update(a[i],1);
84             ans+=i-getsum(a[i]);
85         }
86         printf("Case %d: ",oo++);
87         cout<<ans<<endl;
88     }
89
90
91     return 0;
92 }

时间: 2024-12-16 10:46:01

Gym 100463A Crossings 逆序对的相关文章

CF Gym 100463A树状数组求逆序数

题意:给你一个序列,和标准序列连线,求交点数. 题解:就是求逆序对个数,用数组数组优化就行了. 做八数码的时候,求逆序数搜过怎么求,但是练习时忘了...于是当场想怎么实现,结果搞了1个小时才搞出来,还被WA了个LongLong,基础还不够扎实 #include<cstdio> #include<cmath> #include<vector> #include<map> #include<set> #include<algorithm>

Gym - 101908C 树状数组 逆序对

Grandpa Giuseppe won a professional pizza cutter, the kind of type reel and, to celebrate, baked a rectangle pizza to his grandchildren! He always sliced his pizzas into pieces by making cuts over continuous lines, not necessarily rectilinear, of two

POJ 2299 逆序对

Crossings Time Limit: 2 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100463 Description In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent

codeforces 414C C. Mashmokh and Reverse Operation(归并排序求逆序对)

题目链接: C. Mashmokh and Reverse Operation time limit per test 4 seconds memory limit per test 512 megabytes input standard input output standard output Mashmokh's boss, Bimokh, didn't like Mashmokh. So he fired him. Mashmokh decided to go to university

求逆序对(线段树版)

一个序列a1,a2,a3...aN,求出满足:ai > aj 且 i < j 的个数. 一个最容易想到的方法就是枚举所有的i,j看看是否满足,显然是O(n^2)的复杂度.不够好. 可以这样考虑,开一个数组保存这n个数出现的位置和对应的次数,这个数组要开到a数组里最大的那个数MAX,也就是hash,初始状态数组里没有元素,每个数对应的个数都是0. 如果考虑第i个数,找到比它大的所有的数 的个数,查找的范围即 ai+1~MAX,这就是到i这个位置的逆序对的总和,接着把a[i]这个数添加到数组里,也

剑指offer: 数组中的逆序对

1. 最简单的思路,对每个值,遍历与其逆序的数组对:但时间复杂度太高: 2. 归并排序的思路: 先将数组分隔成子数组,先统计出子数组内的逆序对的数目,然后统计两个相邻子数组之间的逆序对的数目: int InversePairsCore(int *data, int * copy, int start, int end) { //递归介绍条件,只剩一个元素 if(start==end) { copy[start]=data[start]; return 0; } int length=(end-s

[HAOI2009]逆序对数列

题目描述 对于一个数列{ai},如果有i<j且ai>aj,那么我们称ai与aj为一对逆序对数.若对于任意一个由1~n自然数组成的数列,可以很容易求出有多少个逆序对数.那么逆序对数为k的这样自然数数列到底有多少个? 输入输出格式 输入格式: 第一行为两个整数n,k. 输出格式: 写入一个整数,表示符合条件的数列个数,由于这个数可能很大,你只需输出该数对10000求余数后的结果. 输入输出样例 输入样例#1: 4 1 输出样例#1: 3 说明 样例说明: 下列3个数列逆序对数都为1:分别是1 2

bzoj3295动态逆序对

Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 5362  Solved: 1814[Submit][Status][Discuss] Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数. Input 输入第一行包含两个整数n和m,即初始元素的个数和删除的元素个数

【bzoj3295】动态逆序对

我怎么控制不住自己又写了个数据结构啊--真是的-- 其实我是想练CDQ分治的--结果忍不住又写了个主席树. 首先看看不动态的逆序对咋做?树状数组嘛. 那么删除咋搞?就是考虑贡献,把它前面比他大的,后面比他小的减去-- 诶?带修改主席树?我--我好像才写过--? 1 #include<bits/stdc++.h> 2 #define inf 0x7fffffff 3 #define N 100005 4 #define M 5000005 5 using namespace std; 6 typ