1 ≤ n ≤ 5000, 1 ≤ ki ≤ 5000。
#include
#include
#include
struct sc
{
int cnt, count;
long long num[5001];
}p[5010];
struct ms
{
int id;
long long num;
}ans[200000], t[200000];
int sta, end;
void merge(int x, int y)
{
int mid = (x+y)>>1, i = x, j = mid+1, k = x;
while(i != mid+1 && j != y+1)
{
if(ans[i].num > ans[j].num)
{
t[k].id = ans[j].id;
t[k++].num = ans[j++].num;
}
else
{
t[k].id = ans[i].id;
t[k++].num = ans[i++].num;
}
}
while(i <= mid)
{
t[k].id = ans[i].id;
t[k++].num = ans[i++].num;
}
while(j <= y)
{
t[k].id = ans[j].id;
t[k++].num = ans[j++].num;
}
for(i = x; i <= y; ++i)
{
ans[i].id = t[i].id;
ans[i].num = t[i].num;
}
}
void mergesort(int x, int y)
{
if(x < y)
{
int mid = (x+y)>>1;
mergesort(x,mid);
mergesort(mid+1,y);
merge(x,y);
}
}
int main()
{
int n, i, j, k, l = 0, m, sum = 0;
scanf("%d", &n);
for(i = 0; i < n; ++i)
{
long long t1, t2, t3, t4;
k = 0;
scanf("%d %lld %lld %lld %lld", &m, &t1, &t2, &t3, &t4);
l += m;
p[i].cnt = m;
p[i].count = 1;
p[i].num[0] = -1;
p[i].num[1] = t1;
for(j = 2; j <= m; ++j)
{
p[i].num[j] = (p[i].num[j-1] * t2 + t3) % t4;
if(p[i].num[j] < p[i].num[j-1])
k++;
}
if(k > sum)
sum = k;
}
printf("%d\n", sum);
if(l <= 200000)
{
sta = 0;
end = 0;
while(end < l)
{
for(i = 0; i < n; ++i)
{
for(j = p[i].count; j <= p[i].cnt; ++j)
{
if(j != p[i].count && p[i].num[j] < p[i].num[j-1])
{
p[i].count = j;
break;
}
ans[end].id = i;
ans[end++].num = p[i].num[j];
}
if(j > p[i].cnt)//all ascending
p[i].count = j;
}
mergesort(sta,end-1);
sta = end;
}
for(i = 0; i < l; ++i)
printf("%lld %d\n", ans[i].num, ans[i].id+1);
}
return 0;
}
思路:首先我们知道每个科学家的问题的相对顺序无法改变,所以对于每一个科学家的问题其本身的序列就有可能存在坏对,算出每一个科学家的问题的坏对数,记录其中最大的那一个。记为sum,试想无论如何排序,由于科学家问题的顺序限制,所以坏对数最小的值就是sum。那么我们能否在sum坏对数的情况下,合理的安排所有科学家的问题顺序。
答案当然是可以得。我们可以将整个序列进行分层,第一层也就是每一个科学家的问题序列第一次出现坏对的时候(有可能从未出现,那么就是整个序列),我们将这些科学家的第一层的问题统一放到一个数组里进行归并排序,排序完成后再将其存入最终的答案中作为最终答案的第一层序列。第二层以至第sum层都是如此,那么这个序列就是我们要的答案,而且坏对数保证就是sum。
证明:首先对于每一个科学家自身的序列来说,由于我们用的是归并排序,所以绝对不会改变每一个科学家自身序列的相对顺序。其次对于每一层的序列,我们经过排序后肯定是保证严格递增的(即不存在坏对),对于下一层的序列来说同样如此,由于下一层的序列的问题中和上一层的序列的问题中至少存在着一个坏对,所以对于下一层的第一个数(也是最小的那个数)必定是小于上一层的最后一个数的,也就是说保证了2层之间有一个坏对数。那么最终答案就是sum个坏对数,也就是最少的坏对数。