树状数组TLE80分求助,第7、10点TLE。

P3586 [POI2015] LOG

lyndbq @ 2023-07-31 11:09:07

#include<bits/stdc++.h>
using namespace std;

typedef long long LL;

int N, M;
/* t1为种类数, t2为数量和 ,t为上一次修改,L为离散化数组*/
vector<int> O, A, B, L, t;  
vector<LL> t1, t2;

struct quickio 
{
    char ch, sig;

    template <typename _tp>
    inline quickio& operator >> (_tp &num) {
        num = 0, sig = 1, ch = getchar();
        while(ch < '0' || ch > '9') {
            if(ch == '-') sig = -1;
            ch = getchar();
        }
        do {
            num = num * 10 + ch - '0';
            ch = getchar();
        } while(ch >= '0' && ch <= '9');
        num *= sig;
        return *this;
    }
    inline quickio& operator >> (char &tc) {
        do tc = getchar(); while(isspace(tc));
        return *this;
    }

    inline quickio& operator << (char *ts) {
        while(*ts != '\0') putchar(*(ts++));
        return *this;
    }
} qio;

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

void add(vector<LL> &t, int x, int y)
{
    while(x < t.size()){
        t[x] += y;
        x += lowbit(x);
    }
}

LL getsum(vector<LL> &t, int x)
{
    LL sum = 0;
    while(x > 0){
        sum += t[x];
        x -= lowbit(x);
    }
    return sum;
}

int main()
{
    // ios::sync_with_stdio(0);
    // cin.tie(0);cout.tie(0);

    qio >> N >> M;
    char s;

    t.resize(N+1, 0);
    O.resize(M+1,0);
    A.resize(M+1,0);
    B.resize(M+1,0);
    L.resize(M+1,0);

    for(int i=1; i<=M; i++){
        qio >> s >> A[i] >> B[i];
        L[i] = B[i];
        if(s == 'U')
            O[i] = 1;
        else
            O[i] = 0;
    }

    sort(L.begin(), L.end());
    L.erase(unique(L.begin(), L.end()), L.end());

    t1.resize(L.size(),0);
    t2.resize(L.size(),0);

    for(int i=1, x; i<=M; i++){
        B[i] = lower_bound(L.begin(), L.end(), B[i]) - L.begin();

        if(O[i]){
            if(t[A[i]]){
                x = t[A[i]];
                add(t1, x, -1);
                add(t2, x, -L[x]);
            }
            t[A[i]] = B[i];
            x = B[i];
            add(t1, x, 1);
            add(t2, x, L[x]);
        }else{
            int X = getsum(t1, L.size()-1) - getsum(t1, B[i]);   /* 种类数 */
            LL Y = getsum(t2, B[i]);   /* 数量和 */
            if(Y >= (LL)L[B[i]]*(LL)(A[i]-X))
                cout << "TAK" << endl;
            else
                cout << "NIE" << endl;
        }
    }
}

|