TLE 了求助
查看原帖
TLE 了求助
300098
cmaths楼主2024/1/4 08:55
#include <bits/stdc++.h>
#define ll long long

using namespace std;

int read()
{
    int x = 0, f = 1;
    char ch = 0;
    while(!isdigit(ch))
    {
        if(ch == '-')
        {
            f = -1;
        }
        ch = getchar();
    }
    while(isdigit(ch))
    {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

const int M = 400000, N = 800000, LG = 20;
int m, q;
int a[M + 5];

int n;
int s[N + 5];

int sa[N + 5], rk[N + 5];
int id[N + 5], buk[N + 5];
int ork[N + 5];
int ht[N + 5];
int st[N + 5][LG + 5], l2[N + 5];
void bld()
{
    int siz = N;
    for(int i = 1; i <= n; i++)
    {
        buk[rk[i] = s[i]]++;
    }
    for(int i = 1; i <= siz; i++)
    {
        buk[i] += buk[i - 1];
    }
    for(int i = n; i >= 1; i--)
    {
        sa[buk[s[i]]--] = i;
    }
    for(int i = 1; i <= siz; i++)
    {
        buk[i] = 0;
    }
    int cntr = 0;
    for(int w = 1; ; siz = cntr, cntr = 0, w <<= 1)
    {
        int cnti = 0;
        for(int i = n - w + 1; i <= n; i++)
        {
            id[++cnti] = i;
        }
        for(int i = 1; i <= n; i++)
        {
            if(sa[i] > w)
            {
                id[++cnti] = sa[i] - w;
            }
        }

        for(int i = 1; i <= n; i++)
        {
            buk[rk[id[i]]]++;
        }
        for(int i = 1; i <= siz; i++)
        {
            buk[i] += buk[i - 1];
        }
        for(int i = n; i >= 1; i--)
        {
            sa[buk[rk[id[i]]]--] = id[i];
        }
        for(int i = 1; i <= siz; i++)
        {
            buk[i] = 0;
        }

        for(int i = 1; i <= n; i++)
        {
            ork[i] = rk[i];
        }
        for(int i = 1; i <= n; i++)
        {
            rk[sa[i]] = (ork[sa[i]] == ork[sa[i - 1]] && ork[sa[i] + w] == ork[sa[i - 1] + w] ? cntr : ++cntr);
        }
        if(cntr == n)
        {
            break;
        }
    }
    for(int i = 1, k = 0; i <= n; i++)
    {
        if(k)
        {
            k--;
        }
        while(s[i + k] == s[sa[rk[i] - 1] + k])
        {
            k++;
        }
        ht[rk[i]] = k;
    }
    for(int i = 2; i <= N; i++)
    {
        l2[i] = l2[i / 2] + 1;
    }
    for(int i = n; i >= 1; i--)
    {
        st[i][0] = ht[i];
        for(int j = 1; j <= LG; j++)
        {
            if(i + (1 << j) - 1 > n)
            {
                break;
            }
            st[i][j] = min(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
        }
    }
}
int ask(int s, int t)
{
    int tmp = l2[t - s + 1];
    return min(st[s][tmp], st[t - (1 << tmp) + 1][tmp]);
}

void init()
{
    m = read(), q = read();
    for(int i = 1; i <= m; i++)
    {
        a[i] = read();
    }
    for(int i = 2; i <= m; i++)
    {
        s[++n] = a[i] - a[i - 1] + m;
    }
    s[++n] = N;
    for(int i = 2; i <= m; i++)
    {
        s[++n] = a[i - 1] - a[i] + m;
    }
}

vector <int> ve[M + 5];//s chu xian de pai ming
void solve()
{
    bld();
    for(int i = 1; i <= n; i++)
    {
        if(sa[i] <= m - 1)
        {
            ve[a[sa[i]]].push_back(i);
        }
    }
    while(q--)
    {
        int sum = read(), s = read(), t = read();
        int sl, sr;
        int l = 1, r = rk[s + m];
        while(l < r)
        {
            int mid = (l + r) >> 1;
            if(ask(mid + 1, rk[s + m]) >= t - s)
            {
                r = mid;
            }
            else
            {
                l = mid + 1;
            }
        }
        sl = l;
        l = rk[s + m], r = n;
        while(l < r)
        {
            int mid = (l + r + 1) >> 1;
            if(ask(rk[s + m] + 1, mid) >= t - s)
            {
                l = mid;
            }
            else
            {
                r = mid - 1;
            }
        }
        sr = l;
        int val = sum - a[s];
        // printf("%d %d %d\n", sl, sr, val);
        if(val > m || val < 1)
        {
            printf("No\n");
            continue;
        }
        l = 0, r = ve[val].size();
        while(l < r)
        {
            int mid = (l + r) >> 1;
            if(ve[val][mid] >= sl)
            {
                r = mid;
            }
            else
            {
                l = mid + 1;
            }
        }
        if(l == ve[val].size() || ve[val][l] > sr)
        {
            printf("No\n");
            continue;
        }
        printf("Yes\n");
    }
}

int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("test.in", "r", stdin);
    freopen("my.out", "w", stdout);
#endif
    init();
    solve();
    return 0;
}

思路和第二篇题解一致,复杂度 O(qlogn),不知道哪里写挂了 qwq

2024/1/4 08:55
加载中...