传送门
题目描述
Maxim loves sequences, especially those that strictly increase. He is wondering, what is the length of the longest increasing subsequence of the given sequence a a a?
Sequence a a a is given as follows:
the length of the sequence equals
n
×
t
n×t
n×t;
(
1
<
=
i
<
=
n
×
t
)
(1<=i<=n×t)
(1<=i<=n×t) , where operation means taking the remainder after dividing number
x
x
x by number
y
y
y .
Sequence s 1 , s 2 , . . . , s r s_{1},s_{2},...,s_{r} s1,s2,...,sr of length r r r is a subsequence of sequence a 1 , a 2 , . . . , a n a_{1},a_{2},...,a_{n} a1,a2,...,an , if there is such increasing sequence of indexes i 1 , i 2 , . . . , i r i_{1},i_{2},...,i_{r} i1,i2,...,ir ( 1 < = i 1 1<=i_{1} 1<=i1< i 2 i_{2} i2< . . . ... ...< i r < = n i_{r}<=n ir<=n) , that a i j = s j a_{ij}=s_{j} aij=sj . In other words, the subsequence can be obtained from the sequence by crossing out some elements.
Sequence s 1 , s 2 , . . . , s r s_{1},s_{2},...,s_{r} s1,s2,...,sr is increasing, if the following inequality holds: s 1 s_{1} s1< s 2 s_{2} s2< . . . ... ...< s r s_{r} sr .
Maxim have k k k variants of the sequence a a a . Help Maxim to determine for each sequence the length of the longest increasing subsequence.
输入格式
The first line contains four integers k k k , n n n , m a x b maxb maxb and t t t $(1<=k<=10; 1<=n,maxb<=10^{5}; 1<=t<=10^{9}; n×maxb<=2·10^{7}) $ . Each of the next k k k lines contain n n n integers b 1 , b 2 , . . . , b n ( 1 < = b i < = m a x b ) b_{1},b_{2},...,b_{n}(1<=b_{i}<=maxb) b1,b2,...,bn(1<=bi<=maxb) .
Note that for each variant of the sequence a a a the values n n n , m a x b maxb maxb and t t t coincide, the only arrays b b b s differ.
The numbers in the lines are separated by single spaces.
输出格式
Print k k k integers — the answers for the variants of the sequence a a a . Print the answers in the order the variants follow in the input.
题意翻译
给你一个长度为 n n n的 B B B数组, A A A表示 B B B数组复制 t t t遍后首尾相连后的数组,求 A A A的最长上升子序列 有 k k k组询问 m a x b maxb maxb表示 B B B数组中最大的数
输入输出样例
输入 #1
3 3 5 2
3 2 1
1 2 3
2 3 1
输出 #1
2
3
3
解题思路
树状数组中存的是一定包括当前数的最长递增序列长度
Code
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int k,n,maxb,t,ans,sum;
int a[100100],tree[100100],f[100100],b[20000100];
int lowbit (int x)
{
return x & (-x);
}
int find (int x)
{
int ans=0;
for (; x>0; x-=lowbit(x))
ans = max (ans, tree[x]);
return ans;
}
void change (int x, int s)
{
for (; x <= maxb; x+=lowbit (x))
tree[x] = max(tree[x], s);
}
int main()
{
scanf ("%d%d%d%d", &k, &n, &maxb, &t);
while (k--)
{
sum = 0;
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
if (b[a[i]] != k+1)
sum++;
b[a[i]] = k+1;
}
if (sum < t)//t是复制t遍,如果数的数量大于t,那么就表明序列中的数都可以选,直接输出序列有多少数
{
printf ("%d\n", sum);
continue;
}
int ans = 0;
memset (f, 0, sizeof (f));
memset (tree, 0, sizeof (tree));
for (int i = 1; i <= t; i++)
for (int j = 1; j <= n; j++)
{
int x=find (a[j]-1)+1;//必须是递增,所以是求a[j]-1的最长递增序列长度,序列长度加上当前数(+1)
if (f[j] < x)
{
f[j] = x;
ans = max (ans, x);
change (a[j],x);//加入树状数组
}
if (ans >= sum)
break;
}
printf ("%d\n", ans);
}
}