bzoj 1307/1318 玩具 线段树+记录时间戳

玩具

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 743  Solved: 404
[Submit][Status][Discuss]

Description

小球球是个可爱的孩子,他喜欢玩具,另外小球球有个大大的柜子,里面放满了玩具,由于柜子太高了,每天小球球都会让妈妈从柜子上拿一些玩具放在地板上让小球球玩。 这天,小球球把所有的N辆玩具摆成一排放在地上,对于每辆玩具i,小球球都会给它涂上一个正整数value[i],以表示小球球对该玩具的喜爱程度,value[i]越小则表示他越喜爱。当然对于两辆不同的玩具u,v(u<>v),亦有可能value[i]=value[j],也就是说小球球对u,v两车的喜爱程度是一样的。 小球球很贪玩,他希望能从中间某个位置,连续的取出k辆玩具,使得这k辆车里喜爱程度最大的一辆车的喜爱程度正好等于k,且这k辆车中没有两辆车的喜爱程度是相同的。小球球希望知道k的最大值为多少。

Input

第一行一个整数N,表示小球球拥有的玩具数量。 接下来N行,每行一个整数,表示value[i]。

Output

一个整数k,即答案。

Sample Input

6
2
4
1
3
2
1

Sample Output

4

HINT

1<=Value[i]<=10^6
10%的测试数据 N<=10^5。
100%的测试数据 N<=10^6

Source

 

1318: [Spoj744] Longest Permutation

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 608  Solved: 366
[Submit][Status][Discuss]

Description

给你一个序列A含有n个正整数(1<=Ai<=n)。A的子集形式类如Au, Au+1 ... , Av (1<=u<=v<=n),即必须是连续的。我们感兴趣的是一种子集,它含有元素包括1,2,…k。(k是子集的大小)。 你的任务是找到这种类型的最长的子集。

Input

第一行,一个数n,表示序列A的长度 第二行,n个数,第I个数表示元素Ai

Output

一个数,表示可选子集的长度

Sample Input

5
4 1 2 3 2

Sample Output

4

HINT

你可以选得子集从A1开始到A4,这个子集长度为4,包含了1,2,3,4)
1<=n<=100010

Source

 

第一题直接划水,第二题想了想。

第二题题解:可以想到如果两个值相同的话是绝对不能在同一段的

并且它是要连续的,那我们每次加入一个节点时,求出以这个节点结尾的

最大值,怎么求,我用线段树来维护,这棵线段树是一棵权值线段树,

用full表示在这棵子树的所有叶节点是否都有了,然后每个节点记录最小,最大时间戳

表示当前子树中最早与最晚进来的时间,因为每个节点最多只会有一个时间戳,然后

对于删除,就是从头开始一旦两个相同,就将删除指针后移到当前相同的那一个位置+1

每次询问在线段树上二分,左子树如果满了,并且,是当前需要的最迟siz左子树节点就满足

然后去右子树,这是一个递归过程。

 

删除log n ,插入log n 每个值只会插入一次删除一次,正确答案一定有最右断点。

所以总复杂度O(n log n)

 

但是数据比较水,这两道题只需要输出序列的最大值即可。

 1 #pragma GCC optimize(2)
 2 #pragma G++ optimize(2)
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<cstdio>
 7 #include<cstring>
 8 
 9 #define N 27
10 using namespace std;
11 inline int read()
12 {
13     int x=0,f=1;char ch=getchar();
14     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
15     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
16     return x*f;
17 }
18 
19 int n;
20 int a[N];
21 
22 int main()
23 {
24     n=read();int ans=0;
25     for (int i=1;i<=n;i++)
26     {
27         int x=read();
28         ans=max(x,ans);
29     }
30     printf("%d\n",ans);
31 }

 

posted @ 2018-03-01 07:10  Kaiser-  阅读(158)  评论(0编辑  收藏  举报