线段树求优化
  • 板块灌水区
  • 楼主Xiphi
  • 当前回复13
  • 已保存回复13
  • 发布时间2023/5/15 16:23
  • 上次更新2023/10/23 15:40:53
查看原帖
线段树求优化
667250
Xiphi楼主2023/5/15 16:23

跑 n=500000n = 500000 5.17s.... 求优化,优化好久了

题在这里,过了就说明没问题了(无题面

#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx")
// #include <iostream>
#include <stdio.h>
// #include <cstring>
#include <string.h>
// #include <cmath>
#include <math.h>
#define N 1000005
#define INF 0x3f3f3f3f
const int DPAIRSIZ = 1 << 18;
char *p1, *p2, buf[100000];
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++)
int read()
{
    int x = 0;
    int fu = 1;
    char c = getchar();
    while (c > 57 || c < 48)
    {
        if (c == 45)
            fu = -1;
        c = getchar();
    }
    while (c <= 57 && c >= 48)
    {
        x = x * 10 + c - 48;
        c = getchar();
    }
    return x * fu;
}
int maxx(int x, int y)
{
    return x > y ? x : y;
}
int minnn(int x, int y)
{
    return x < y ? x : y;
}
int n, a[N], L, R;
int maxn[(N << 2) + 1];
int minn[(N << 2) + 1];
#define push_up(k) maxn[k] = maxx(maxn[k << 1], maxn[k << 1 | 1])
#define push_up1(k) minn[k] = minnn(minn[k << 1], minn[k << 1 | 1])
void build(int l, int r, int k)
{
    if (l == r)
    {
        maxn[k] = a[l];
        return;
    }
    int mid = (l + r) >> 1;
    build(l, mid, k << 1);
    build(mid + 1, r, k << 1 | 1);
    push_up(k);
}
int ql, qr;
int query(int l, int r, int k)
{
    int ret = -INF;
    if (l >= ql && r <= qr)
        return maxn[k];
    int mid = (l + r) >> 1;
    if (ql <= mid)
        ret = maxx(ret, query(l, mid, k << 1));
    if (qr > mid)
        ret = maxx(ret, query(mid + 1, r, k << 1 | 1));
    return ret;
}
void build1(int l, int r, int k)
{
    if (l == r)
    {
        minn[k] = a[l];
        return;
    }
    int mid = (l + r) >> 1;
    build1(l, mid, k << 1);
    build1(mid + 1, r, k << 1 | 1);
    push_up1(k);
}
int query1(int l, int r, int k)
{
    int ret = INF;
    if (l >= ql && r <= qr)
        return minn[k];
    int mid = (l + r) >> 1;
    if (ql <= mid)
        ret = minnn(ret, query1(l, mid, k << 1));
    if (qr > mid)
        ret = minnn(ret, query1(mid + 1, r, k << 1 | 1));
    return ret;
}

int check(int tl, int tr)
{
    ql = tl, qr = tr;
    int judge1 = query(1, n, 1), judge = query1(1, n, 1);
    if (L <= judge1 - judge && judge1 - judge <= R)
    {
        return 1;
    }
    else
        return 0;
}

int Ans = 0, l, r, ans1, ans2, i, judge, judge1;
int main()
{
    // cin >> n >> L >> R;
    n = read();
    L = read();
    R = read();
    memset(a, 0, sizeof a);
    for (int i = 1; i <= n; i = -~i)
        read(a[i]);
    memset(maxn, 0, sizeof maxn);
    memset(minn, 0, sizeof minn);
    build(1, n, 1), build1(1, n, 1);
    for (i = 1; i <= n; i = -~i)
    {
        l = i, r = n, ans1 = i, ans2 = i;
        while (l <= r)
        {
            int mid = l + r >> 1;
            int tl = i, tr = mid;
            ql = tl, qr = tr;
            judge1 = query(1, n, 1), judge = query1(1, n, 1);
            if (L <= judge1 - judge && judge1 - judge <= R)
                ans1 = mid, l = mid + 1;
            else
            {
                if (judge1 - judge > R)
                    r = mid - 1;
                else
                    l = mid + 1;
            }
        }
        l = i, r = n;
        while (l <= r)
        {
            int mid = l + r >> 1;
            int tl = i, tr = mid;
            ql = tl, qr = tr;
            judge1 = query(1, n, 1), judge = query1(1, n, 1);
            if (L <= judge1 - judge && judge1 - judge <= R)
                ans2 = mid, r = mid - 1;
            else
            {
                if (judge1 - judge > R)
                    r = mid - 1;
                else
                    l = mid + 1;
            }
        }
        if (check(i, ans1) || check(i, ans2))
            Ans += (ans1 - ans2) + 1;
    }
    // cout << Ans;
    printf("%d", Ans);
    return 0;
}
2023/5/15 16:23
加载中...