// This file is generated by mkfile.py
// Date: 2026-06-26

#include <solution/32.h>

#include <stdlib.h>
#include <string.h>

#define max(x, y) ((x) > (y) ? (x) : (y))

int longestValidParentheses(char *s)
{
    int result = 0;
    int m = strlen(s);

    if (m < 2)
        return result;

    int *dp = malloc(sizeof(int) * m);
    memset(dp, 0, sizeof(int) * m);

    //     i: current index, we skipped 0 because one char can not
    //        be paired
    // dp[i]: use i as the end of string, see how much parentheses
    //        can be matched before i
    for (int i = 1; i < m; i++)
    {
        // if current char is "(" it can not be matched, a valid
        // match must be ended with ")". we just check s[i] == ')'
        if (s[i] == ')')
        {
            // so there are 2 match situations:
            // 1. s[i - 1] == '('. it can match current ')'. we also
            //    need to check before it if we had a valid pair.
            if (s[i - 1] == '(')
            {
                if (i > 1)
                    dp[i] = dp[i - 2] + 2;
                else
                    dp[i] = 2;
                continue;
            }
            // 2. s[i - 1] == ')'. it means there maybe has valid pair
            //    before. we need to know how much pairs before i. we
            //    can read it from dp[i], then we can get char before
            //    valid pair. like situation 1, if char == '(' it can
            //    be matched. but we need to noticed, if there is no
            //    valid pair before, this ')' must be ignored.
            int k = i - dp[i - 1] - 1;
            if (k < 0)
                continue;

            if (s[k] == '(')
            {
                // if k > 1, see if we can add a valid pair before k
                if (k > 1)
                    dp[i] = dp[i - 1] + dp[k - 1] + 2;
                else
                    dp[i] = dp[i - 1] + 2;
            }
        }
    }

    for (int i = 0; i < m; i++)
        result = max(dp[i], result);

    free(dp);
    return result;
}