LOJ6281ブロック記入欄5

LOJ6281の ブロックエントリ5の列数

タグ

  • ブロックエントリ

序文

  • ノー

質問の簡潔な意味

  • メンテナンスシーケンスは、両方の操作をサポートする必要があります
    1. インターバル平方根
    2. プラスレンジ

考え

  • 学生は確かに木の回線に問題の間隔平方根を達成するために行っているツリーラインを学びました。トピックはフローラ何であるように見えます
  • 実際には、ほとんどのツリーラインで行うことを阻止します。2e31は、オープン5回平方根の数が1になることに留意、私たちは直接[]ルート番号の各部分が開いていないどのくらいの約レコードを配列タグを開きます。次に、動作を変更し、ブロックは、タグの部分++で記録時、根に直接開いていません。クエリ操作は、モノリシックではない直接追加、ブロックタグ> = 5は、それがある場合、ピースが1であるかどうか、ANSプラス直接LEN。それ以外の場合、この一対一ではうまく処理します。

注意事項

  • まず、我々は細部に注意を払う必要があります。で、非ブロックを扱うには、タグ[POS [I]]、および処理ブロックを覚えているとき、私はタグ[i]にして、テーブルブロックを取りました。
  • もう一つは、平方根は特別な裁判官が見て0 0、で、です。要するに、それは特別な文に約0を考え平方根になります。

概要

  • ノー

ACコード

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;

const int maxn = 1e5 + 10;

int n, a[maxn];
int pos[maxn], len, tag[maxn], is_zero[maxn], num[maxn];

void change(int l, int r, int c)
{
    for (int i = l; i <= min(len * pos[l], r); i++)
        a[i] = sqrt(a[i]);

    if (pos[l] != pos[r])
        for (int i = r; i >= len * pos[r] - len + 1; i--)
            a[i] = sqrt(a[i]);

    for (int i = pos[l] + 1; i <= pos[r] - 1; i++)
        tag[i]++;
}

int cal(int l, int r, int c)
{
    int ans = 0;
    for (int i = l; i <= min(len * pos[l], r); i++)
    {
        if (a[i] == 0)
            continue;
        if (tag[pos[i]] >= 5)
            ans += 1;
        else
        {
            int t = a[i];
            for (int j = 1; j <= tag[pos[i]]; j++)
                t = sqrt(t);
            ans += t;
        }
    }
    
    if (pos[l] != pos[r])
        for (int i = r; i >= len * pos[r] - len + 1; i--)
        {
            if (a[i] == 0)
                continue;
            if (tag[pos[i]] >= 5)
                ans += 1;
            else
            {
                int t = a[i];
                for (int j = 1; j <= tag[pos[i]]; j++)
                    t = sqrt(t);
                ans += t;
            }
        }

    for (int i = pos[l] + 1; i <= pos[r] - 1; i++)
    {
        if (tag[i] >= 5)
            ans += len - num[i];
        else
        {
            for (int j = i * len - len + 1; j <= i * len; j++)
            {
                int t = a[j];
                for (int k = 1; k <= tag[i]; k++)//开方k次
                    t = sqrt(t);
                ans += t;
            }
        }
    }

    return ans;
}

void solve()
{
    scanf("%d", &n);
    len = sqrt(n);
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]), pos[i] = (i - 1) / len + 1;
        if (a[i] == 0)
            is_zero[i] = 1, num[pos[i]]++;
    }

    for (int i = 1; i <= n; i++)
    {
        int opt, l, r, c;
        scanf("%d%d%d%d", &opt, &l, &r, &c);
        if (opt == 0)
            change(l, r, c);
        else
            printf("%d\n", cal(l, r, c));
    }
}

int main()
{
    //freopen("Testin.txt", "r", stdin);
    //freopen("Testout.txt", "w", stdout);
    solve();
    return 0;
}

おすすめ

転載: www.cnblogs.com/danzh/p/11361119.html