树状数组50ptsTLE求条

P3793 由乃救爷爷

asd890123 @ 2024-07-25 09:16:11

期望单次复杂度O(logn),总复杂度O(mlogn + nlogn)+小常数,为啥还T,code:

#include <iostream>
#include <cstring>

namespace GenHelper
{
    unsigned z1,z2,z3,z4,b;
    unsigned rand_()
    {
    b=((z1<<6)^z1)>>13;
    z1=((z1&4294967294U)<<18)^b;
    b=((z2<<2)^z2)>>27;
    z2=((z2&4294967288U)<<2)^b;
    b=((z3<<13)^z3)>>21;
    z3=((z3&4294967280U)<<7)^b;
    b=((z4<<3)^z4)>>12;
    z4=((z4&4294967168U)<<13)^b;
    return (z1^z2^z3^z4);
    }
}
void srand(unsigned x)
{using namespace GenHelper;
z1=x; z2=(~x)^0x233333333U; z3=x^0x1234598766U; z4=(~x)+51;}
int read()
{
    using namespace GenHelper;
    int a=rand_()&32767;
    int b=rand_()&32767;
    return a*32768+b;
}

#define N 20000005

__uint32_t s;
int n,m,a[N],tree[N];
__uint64_t ans = 0;

__always_inline static int lowbit(int x){return x & -x;}

__always_inline static void modify(int x,int y){

    for (;x <= n;x += lowbit(x)){

        if (tree[x] < y) tree[x] = y;
        else break;

    }

}

inline static int FindMax(const int &x,const int &y){

    if (y > x){

        if (y - lowbit(y) > x) return std::max(tree[y],FindMax(x,y - lowbit(y)));
        else return std::max(a[y],FindMax(x,y - 1));

    }

    return a[x];
}

int main(){

    #ifndef ONLINE_JUDGE
        freopen("P3793.in","r",stdin);
    #endif

    scanf("%d%d%u",&n,&m,&s);
    srand(s);
    memset(tree,0x80,sizeof(tree));
    for (int i = 1;i <= n;i++) modify(i,a[i] = read());
    while (m--){

        int l = read() % n + 1,r = read() % n + 1;

        if (l > r) std::swap(l,r);
        ans += FindMax(l,r);

    }
    printf("%lu\n",ans);

    return 0;
}

by M1saka16I72 @ 2024-07-25 09:55:17

热知识:树状数组维护不可差分信息单次查询的复杂度是 \mathcal{O}(\log^2 n)


by george0929 @ 2024-08-04 10:11:06

这题要求线性做法(不然为啥数据随机)


|