Submission #261509

#TimeUsernameProblemLanguageResultExecution timeMemory
261509KastandaStreet Lamps (APIO19_street_lamps)C++11
100 / 100
3419 ms233164 KiB
// M
#include<bits/stdc++.h>
#define lc (id << 1)
#define rc (lc ^ 1)
#define md ((l + r) >> 1)
using namespace std;
const int N = 300005, MXS = N * 4, MXF = N * 19;
int n, q, ts, TP[N], qa[N], qb[N], St[MXS], F[MXF];
char A[N];
set < int > ST;
map < pair < int , int > , int > MP;
vector < int > V[N], VS[MXS], fcl[MXS], fcr[MXS];
inline void AddFen(int i, int val)
{
        for (i ++; i < MXF; i += i & - i)
                F[i] += val;
}
inline int GetFen(int i)
{
        int rt = 0;
        for (i ++; i; i -= i & - i)
                rt += F[i];
        return rt;
}
inline void AddFen(int l, int r, int val)
{
        AddFen(l, val);
        AddFen(r, -val);
}
void Build(int id = 1, int l = 1, int r = n + 2)
{
        if (r - l < 2)
        {
                VS[id] = V[l];
                St[id] = ts;
                ts += (int)VS[id].size();
                return ;
        }
        Build(lc, l, md);
        Build(rc, md, r);
        merge(VS[lc].begin(), VS[lc].end(), VS[rc].begin(), VS[rc].end(), back_inserter(VS[id]));
        VS[id].resize(unique(VS[id].begin(), VS[id].end()) - VS[id].begin());
        int le = 0, ri = 0;
        for (int a : VS[id])
        {
                while (le < (int)VS[lc].size() && VS[lc][le] < a)
                        le ++;
                while (ri < (int)VS[rc].size() && VS[rc][ri] < a)
                        ri ++;
                fcl[id].push_back(le);
                fcr[id].push_back(ri);
        }
        fcl[id].push_back((int)VS[lc].size());
        fcr[id].push_back((int)VS[rc].size());
        St[id] = ts;
        ts += (int)VS[id].size();
}
void AddSeg(int le, int ri, int val, int lq, int rq, int id = 1, int l = 1, int r = n + 2)
{
        if (ri <= l || r <= le || rq <= lq)
                return ;
        if (le <= l && r <= ri)
                return void(AddFen(St[id] + lq, St[id] + rq, val));
        AddSeg(le, ri, val, fcl[id][lq], fcl[id][rq], lc, l, md);
        AddSeg(le, ri, val, fcr[id][lq], fcr[id][rq], rc, md, r);
}
int GetSeg(int i, int b, int id = 1, int l = 1, int r = n + 2)
{
        int rt = GetFen(St[id] + b);
        if (r - l < 2)
                return rt;
        if (i < md)
                return GetSeg(i, fcl[id][b], lc, l, md) + rt;
        return GetSeg(i, fcr[id][b], rc, md, r) + rt;
}
inline void Add(int l, int r, int val)
{
        r ++; // Changing segments to points
        if (!val) return ;
        int lq = lower_bound(VS[1].begin(), VS[1].end(), l) - VS[1].begin();
        int rq = lower_bound(VS[1].begin(), VS[1].end(), r) - VS[1].begin();
        AddSeg(l, r, val, lq, rq);
}
inline int Get(int a, int b)
{
        b = lower_bound(VS[1].begin(), VS[1].end(), b) - VS[1].begin();
        return GetSeg(a, b);
}
inline void TurnOff(int i, int tnw)
{
        assert(A[i]); A[i] = 0;
        auto it = ST.lower_bound(i);
        int ri = * it; it --;
        int le = * it;
        le ++; ri --;
        ST.insert(i);

        Add(le, ri + 1, tnw - MP[{le, ri}]);
        MP[{le, ri}] = -1;

        if (le < i)
                MP[{le, i - 1}] = tnw;
        if (i < ri)
                MP[{i + 1, ri}] = tnw;
}
inline void TurnOn(int i, int tnw)
{
        assert(!A[i]); A[i] = 1;
        ST.erase(i);
        auto it = ST.lower_bound(i);
        int ri = * it; it --;
        int le = * it;
        le ++; ri --;

        if (le < i)
                Add(le, i, tnw - MP[{le, i - 1}]);
        if (i < ri)
                Add(i + 1, ri + 1, tnw - MP[{i + 1, ri}]);

        MP[{le, ri}] = tnw;
}
int main()
{
        scanf("%d%d%s", &n, &q, &A[1]);
        for (int i = 1; i <= q; i ++)
        {
                char ss[10];
                scanf("%s%d", ss, &qa[i]);
                if (ss[0] == 'q')
                        scanf("%d", &qb[i]), TP[i] = 1, V[qa[i]].push_back(qb[i]);
                else
                        TP[i] = 2;
        }
        for (int i = 1; i <= n + 1; i ++)
                sort(V[i].begin(), V[i].end());
        Build();
        for (int i = 1; i <= n; i ++)
                A[i] -= '0';
        ST.insert(0);
        ST.insert(n + 1);
        for (int i = 1; i <= n; i ++)
                if (!A[i])
                        ST.insert(i);
        for (int i = 1; i <= n; i ++)
                if (A[i] && !A[i - 1])
                {
                        int r = i;
                        while (r <= n && A[r])
                                r ++;
                        MP[{i, r - 1}] = 0;
                }
        for (int i = 1; i <= q; i ++)
        {
                if (TP[i] == 2)
                {
                        if (A[qa[i]])
                                TurnOff(qa[i], i);
                        else
                                TurnOn(qa[i], i);
                        continue;
                }
                int a = qa[i], b = qb[i];
                if (A[a])
                        TurnOff(a, i), TurnOn(a, i);
                printf("%d\n", Get(a, b));
        }
        return 0;
}

Compilation message (stderr)

street_lamps.cpp: In function 'int main()':
street_lamps.cpp:124:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf("%d%d%s", &n, &q, &A[1]);
         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
street_lamps.cpp:128:22: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
                 scanf("%s%d", ss, &qa[i]);
                 ~~~~~^~~~~~~~~~~~~~~~~~~~
street_lamps.cpp:130:55: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
                         scanf("%d", &qb[i]), TP[i] = 1, V[qa[i]].push_back(qb[i]);
                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...