제출 #1331140

#제출 시각아이디문제언어결과실행 시간메모리
1331140iamhereforfun가로등 (APIO19_street_lamps)C++20
100 / 100
1002 ms96524 KiB
// Starcraft 2 enjoyer //

#include <bits/stdc++.h>

// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")

using namespace std;

#define LSOne(X) ((X) & -(X))
#define int long long

const int N = 3e5 + 5;
const int LG = 18;
const int C = 26;
const int K = 7;
const long long INF = 1e18;
const int B = 700;
const int MOD = 998244353;

struct Fenwick
{
    vector<int> ft;
    int n;
    void build(int len)
    {
        n = len;
        ft.assign(n + 1, 0);
    }
    void update(int pos, int val)
    {
        while (pos <= n)
        {
            ft[pos] += val;
            pos += LSOne(pos);
        }
    }
    int get(int pos)
    {
        int sum = 0;
        while (pos > 0)
        {
            sum += ft[pos];
            pos -= LSOne(pos);
        }
        return sum;
    }
} ft;

struct Query
{
    int type;
    int x, y;
    int val;
};

int n, q, ans[N];
string s;
vector<Query> events;
set<array<int, 2>> seg;

bool cmp(Query &a, Query &b)
{
    return a.x < b.x;
}

void add(int x1, int y1, int x2, int y2, int v)
{
    // cout << x1 << " " << x2 << " " << v << "id\n";
    events.push_back({0, x1, y1, v});
    events.push_back({0, x2 + 1, y1, -v});
    events.push_back({0, x1, y2 + 1, -v});
    events.push_back({0, x2 + 1, y2 + 1, v});
}

void dnc(int l, int r)
{
    if (l >= r)
        return;
    int m = (l + r) / 2;
    dnc(l, m);
    dnc(m + 1, r);
    vector<Query> left, right;
    for (int x = l; x <= m; x++)
    {
        if (events[x].type == 0)
        {
            left.push_back(events[x]);
        }
    }
    for (int x = m + 1; x <= r; x++)
    {
        if (events[x].type == 1)
        {
            right.push_back(events[x]);
        }
    }
    sort(left.begin(), left.end(), cmp);
    sort(right.begin(), right.end(), cmp);
    int ptr = 0;
    for (int x = 0; x < right.size(); x++)
    {
        while (ptr < left.size() && left[ptr].x <= right[x].x)
        {
            // cout << left[ptr].val << "\n";
            ft.update(left[ptr].y, left[ptr].val);
            ptr++;
        }
        // cout << right[x].x << " " << right[x].y << " " << ft.get(right[x].y) << " " << "val\n";
        ans[right[x].val] += ft.get(right[x].y);
    }
    for (int x = 0; x < ptr; x++)
    {
        ft.update(left[x].y, -left[x].val);
    }
}

inline void solve()
{
    cin >> n >> q >> s;
    ft.build(n + 1);
    s = " " + s;
    for (int x = 1; x <= n; x++)
    {
        if (s[x] == '1')
        {
            int j = x;
            while (j <= n && s[j] == '1')
                j++;
            seg.insert({x, j - 1});
            x = j;
        }
    }
    for (int x = 1; x <= q; x++)
    {
        string t;
        ans[x] = -1;
        cin >> t;
        if (t == "toggle")
        {
            int i;
            cin >> i;
            if (s[i] == '0') // on
            {
                s[i] = '1';
                int al = i, ar = i;
                auto it = seg.upper_bound({i, n + 1});
                if (it != seg.end())
                {
                    auto [l, r] = *it;
                    if (l == i + 1)
                    {
                        ar = r;
                        seg.erase(it);
                    }
                }
                // cout << al << " " << ar << "w\n";
                it = seg.upper_bound({i, n + 1});
                if (it != seg.begin())
                {
                    it--;
                    auto [l, r] = *it;
                    if (r == i - 1)
                    {
                        al = l;
                        seg.erase(it);
                    }
                }
                add(al, i, i, ar, -x);
                // cout << al << " " << ar << "\n";
                seg.insert({al, ar});
            }
            else // off
            {
                s[i] = '0';
                auto it = seg.upper_bound({i, n + 1});
                it--;
                auto [l, r] = *it;
                seg.erase(it);
                // cout << l << " " << r << "\n";
                if (l < i)
                {
                    seg.insert({l, i - 1});
                }
                if (r > i)
                {
                    seg.insert({i + 1, r});
                }
                add(l, i, i, r, x);
            }
        }
        else
        {
            ans[x] = 0;
            int l, r;
            cin >> l >> r;
            r--;
            events.push_back({1, l, r, x});
            auto it = seg.upper_bound({l, n + 1});
            if (it != seg.begin())
            {
                it--;
                auto [cl, cr] = *it;
                if (cl <= l && r <= cr)
                {
                    ans[x] += x;
                }
            }
        }
        // cout << x << " " << seg.size() << "v\n";
        // for (auto &[l, r] : seg)
        // {
        //     cout << l << " " << r << "\n";
        // }
        // cout << "\n";
    }
    dnc(0, events.size() - 1);
    for (int x = 1; x <= q; x++)
    {
        if (ans[x] < 0)
            continue;
        cout << ans[x] << "\n";
    }
}

signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    // cin >> t;
    for (int x = 1; x <= t; x++)
    {
        solve();
    }
    return 0;
}
#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...