After the last wardevastated your country, you - as the king of the land of Armenian - decided itwas high time to improve the defense of your capital city. A part of yourfortification is a line of mage towers, starting near the city and continuingto the northern woods. Your advisors determined that the quality of the defensedepended only on one factor: the length of a longest contiguous tower sequenceof increasing heights. (They gave you a lengthy explanation, but the only thingyou understood was that it had something to do with firing energy bolts atenemy forces).
After some hard negotiations,it appeared that building new towers is out of question. Mages of Armenian haveagreed to demolish some of their towers, though. You may demolish arbitrarynumber of towers, but the mages enforced one condition: these towers have to beconsecutive.
For example, ifthe heights of towers were, respectively, 5, 3, 4, 9, 2, 8, 6, 7, 1, then bydemolishing towers of heights 9, 2, and 8, the longest increasing sequence ofconsecutive towers is 3, 4, 6, 7.
The input containsseveral test cases. The first line of the input contains a positive integer Z25, denoting the number oftest cases. Then Z test cases follow, each conforming to theformat described below.
The input instanceconsists of two lines. The first one contains one positive integer n2 .105 denotingthe number of towers. The second line contains n positiveintegers not larger than 109 separated by single spacesbeing the heights of the towers.
For each testcase, your program has to write an output conforming to the format describedbelow.
You should outputone line containing the length of a longest increasing sequence of consecutivetowers, achievable by demolishing some consecutive towers or no tower at all.
2
9
5 3 4 9 2 8 6 7 1
7
1 2 3 10 4 5 6
4
6
代码:
#include<cstdio>
#include<set>
#include<cassert>
using namespacestd;
const int maxn =200000 + 5;
int n, a[maxn],f[maxn], g[maxn];
struct Candidate
{
int a, g;
Candidate(int a, int g):a(a),g(g) {}
bool operator < (const Candidate& rhs)const
{
return a < rhs.a;
}
};
set<Candidate>s;
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
if(n == 1)
{
printf("1\n");
continue;
}
//g[i] is thelength of longest increasing continuous subsequence ending at i
g[0] = 1;
for(int i = 1; i < n; i++)
{
if(a[i-1] < a[i])
{
g[i] = g[i-1] + 1;
}
else
{
g[i] = 1;
}
}
//f[i] is thelength of longest increasing continuous subsequence starting from i
f[n-1] = 1;
for(int i = n-2; i >= 0; i--)
{
if(a[i] < a[i+1])
{
f[i] = f[i+1] + 1;
}
else
{
f[i] = 1;
}
}
s.clear();
s.insert(Candidate(a[0], g[0]));
int ans = 1;
for(int i = 1; i < n; i++)
{
Candidate c(a[i], g[i]);
set<Candidate>::iterator it =s.lower_bound(c); // first one that is >= c
bool keep = true;
if(it != s.begin())
{
Candidate last = *(--it); //(--it) points to the largest one that is < c
int len = f[i] + last.g;
ans = max(ans, len);
if(c.g <= last.g)
{
keep = false;
}
}
if(keep)
{
s.erase(c);// if c.a is alreadypresent, the old g must be <= c.g
s.insert(c);
it = s.find(c); //this is a bit cumbersome and slow but it'sclear
it++;
while(it != s.end() &&it->a > c.a && it->g <= c.g)
{
s.erase(it++);
}
}
}
printf("%d\n", ans);
}
return 0;
}