[Group] JZOJ2019.01.25 NOIP improved analog portion subject group B

3894. transformation of binary tree

Description

Small Y saw a presentation about the school at the time of binary tree theory: In computer science, a binary tree every node has at most two sub-ordered tree nodes. Usually the child nodes called "child left" and "right child." Binary tree is used as a binary search tree and a binary heap. He then discussed and others played a binary search tree.
What is the binary search trees? Binary search tree is a binary tree first. Provided key [p] denotes the value on node p. For which each node p, if it exists left child LCH, the key [p]> key [lch ]; if it is present right child Rch, the key [p] <key [rch ]; noted that the question of should satisfy the binary search tree for all nodes, which is key in the left subtree of the current node's key is less than that of the right subtree of the current key is greater than the node key.
Small Y content is discussed with others, now given a binary tree can change the value of any node. Modify a node count value of last modification, and this node can not be modified. To turn it into a binary search tree, and the value at any time the node must be an integer (which may be negative or zero integer), the desired minimum number of modifications.
I believe this must not beat you! Please help small Y solve this problem now.

Input

The first line of a positive integer and n represents a binary tree of nodes. Node are numbered from 1 ~ n.
The second row of n positive integers separated by spaces, ai represents the i-th node i of the original values.
After n - 1 lines each two non-negative integers fa, ch, row i + 2 of the description father node number i + fa 1, and a parent-child relationship ch, (ch = 0 i + 1 indicates the left son, CH i + 1 = 1 for the right son).
1 is always the root node of the binary tree.

Output

Only one row contains an integer indicating the minimum number of modifications.

Sample Input

3
2 2 2
1 0
1 1

Sample Output

2

Data Constraint

20 % :n <= 10 , ai <= 100.

40 % :n <= 100 , ai <= 200

60 % :n <= 2000 .

100 % :n <= 10 ^ 5 , ai < 2 ^ 31.

solution

Preorder + LIS (maximum length sequence drop)

Such a binary tree has about the relationship between son and most widespread parent node weights can be traversed by X-sequence inflicted a series operation, similar to the 2018 semi-finals last group of the popularity of a problem positive solution to this problem must preorder.

The LIS n ^ 2 approach can only take 60 out of practice monotone nlogn queue, here are some details to note:

  1. Because the weight must be an integer points, it is necessary to perform an operation sequence preorder provided as a [i], each put a [i] - i, when doing so does not decrease the longest sequence can be ensure that the two intermediate discontinuous integer entries may be modified, such as 2 1 3 4, LIS obtains only a modified, but actually to modify twice, after the operation is 1-100, correctly.

  2. It does not fall with the longest sequence rather than the longest sequence rises, because the operation of 1, see examples cited.

  3. The final two sharing refers d l array (defined as a blog and paste) the new position of the minimum value is greater than k, r is smaller than the new value of k means the maximum position

Code

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N = (int)1e5 + 10;
int n, v[N], son[N][2], a[N], d[N], len = 1;
void build(int u)
{
    if (!u) return;
    build(son[u][0]);
    a[++a[0]] = v[u];
    build(son[u][1]);
}
void find(int k)
{
    int l = 1, r = len;
    while (l <= r)
    {
        int mid = (l + r) / 2;
        if (d[mid] <= k)
            l = mid + 1;
        else
            r = mid - 1;
    }
    d[l] = k;
}
void lis()
{
    d[len] = a[1];
    for (int i = 2; i <= n; i++)
    {
        if (a[i] >= d[len]) d[++len] = a[i];
        else find(a[i]);
    }
}
int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%d", &v[i]);
    for (int i = 2; i <= n; i++)
    {
        int u, k;
        scanf("%d%d", &u, &k);
        son[u][k] = i;
    }
    build(1);
    for (int i = 1; i <= n; i++) a[i] -= i;
    lis();
    printf("%d\n", n - len);
    return 0;
}

LIS nlogn practice: https://www.cnblogs.com/itlqs/p/5743114.html

3895. figures for

Description

H is a little thoughtful student, and now she was thinking about a question related to the sequence.
A length in front of her emerges out of n of the sequence {ai}, she wants to find some interval L, R & lt .
This particular range is satisfied, the presence of a k (L <= k <= R), and for arbitrary i (L <= i <= R), ai can be divided ak. Such a particular interval [L, R] values of R - L.
Small H wants to know the maximum value in the sequence is the number of all special sections, the number of such intervals and have it? And these intervals are, what does? Can you help her.

Input

The first line, an integer n.
The second row, n-integers, representing ai.

Output

The first line of two integers, num and val, and the maximum value is the number of maximum value of the special section.
The second row num integers, the maximum value of the output of each special section ascending L.

Sample Input

输入1:
5
4 6 9 3 6
输入2:
5
2 3 5 7 11

Sample Output

输出1:
1 3
2
输出2:
5 0
1 2 3 4 5

Data Constraint

30%: 1 <= n <= 30 , 1 <= ai <= 32.

60%: 1 <= n <= 3000 , 1 <= ai <= 1024.

80%: 1 <= n <= 300000 , 1 <= ai <= 1048576.

100%: 1 <= n <= 500000 , 1 <= ai < 2 ^ 31.

solution

Violence, the minimum number of enumeration, with l, r two pointers, can not be extended to the minimum number of expansion jump directly to the position of r + 1, r + 1 if the number is a factor of the minimum of the original pointer unchanged l, or l = r + 1

Be careful not coupled with records of all minimum and then jumping l pointer optimization, will repeat

Code

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N = 500010;
int n, a[N], ans[N], l, r, k = 1, len = 0, lnum, rnum;
int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    l = r = k;
    while (k <= n)
    {
        while (l > 1 && a[l - 1] % a[k] == 0) l--;
        while (r < n && a[r + 1] % a[k] == 0) r++;
        if (r - l > len)
        {
            len = r - l;
            memset(ans, 0, sizeof ans);
            ans[++ans[0]] = l;
        }
        else if (r - l == len) ans[++ans[0]] = l;
        if (r >= n) break;
        if (a[k] % a[r + 1]) l = r = r + 1;
        else r = r + 1;
        k = r;
    }
    if (!len)
    {
        printf("%d 0\n", n);
        for (int i = 1; i <= n; i++) printf("%d ", i);
        return 0;
    }
    printf("%d %d\n", ans[0], len);
    for (int i = 1; i <= ans[0]; i++) printf("%d ", ans[i]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/featherZHY/p/11334083.html