CPC23 2014-1 B.Crossings(求逆序数)
来源:互联网 发布:淘宝联盟 高佣活动 编辑:程序博客网 时间:2024/05/21 14:07
题目链接:http://acm.hrbust.edu.cn/
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).
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.
OutputFor 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 Input5 2 1
19 12 7
0 0 0
Sample OutputCase 1: 3
Case 2: 77
题目大意:通过如题所述变换,如图,求交叉点个数。由于通过变换位置得到的交叉,提到前面的数字自然会与放在后面的数字形成交叉,也就是求逆序数即可。
采用归并排序nlog(n)的求逆序数方式可过。
AC代码(2443ms):
#include <cstdio>#define MAXN 1000010using namespace std;typedef long long LL;LL n, x, y;LL a[MAXN], tmp[MAXN];long long result;void merge(int l, int mid, int r) { int i, j, k; i = l, j= mid + 1, k = 1; while(i<= mid && j <= r) { if(a[j] < a[i]) { tmp[k++] = a[j++]; result += mid - i + 1; } else tmp[k++] = a[i++]; } while(i <= mid) tmp[k++] = a[i++]; while(j <= r) tmp[k++] = a[j++]; for(i = l, k = 1; i<= r; i++, k++) a[i] = tmp[k];}void merge_sort(int l, int r) { if(l < r) { int mid = (l + r) / 2; merge_sort(l, mid); merge_sort(mid + 1, r); merge(l, mid, r); }}int main() { int cnt = 0; while(~scanf("%lld%lld%lld", &n, &x, &y)) { if(n == 0) break; for(int i = 1; i <= n; i++) { a[i] = (x * (LL)(i - 1) + y) % n; } result = 0LL; merge_sort(1, n); printf("Case %d: %lld\n", ++cnt, result); } return 0;}
PS:此题可能是卡了下线段树的常数2nlog(n),导致T了= =|||
- CPC23 2014-1 B.Crossings(求逆序数)
- 求逆序数
- 求逆序数
- 求逆序数
- 求逆序数
- 求逆序数
- 求逆序数
- 求逆序数
- 求逆序数
- 求逆序数算法
- 求逆序数
- 求逆序数#no
- 求逆序数
- NYOJ117 求逆序数
- 求逆序数
- 求序列逆序数
- nyoj117求逆序数
- NYOJ 求逆序数
- mfc 单文档打开BMP
- php实现简明英汉词典
- POJ3661——Running
- apache + svn Can't open file '*/txn-current-lock': Permission denied
- 九度OJ[1002]
- CPC23 2014-1 B.Crossings(求逆序数)
- leetcode_题解_Merge Sorted Array _简单题
- python列表过滤
- Java 读取Excel文件
- 工作笔记--IE下easyui datagrid url传参数到后台出现乱码
- Java匿名内部类
- ACM HDU 4833
- 使用apache htpasswd生成加密的密码文件,并使用.htaccess控制目录访问
- TIOBE11月编程语言排行榜:R受大数据影响跃至12位