【luoguCF261D】【CF261D】【树状数组】Maxim and Increasing Subsequence

传送门

题目描述

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);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值