分块板子整理

分块

tot = cnt = 1;
d = sqrt(n);

for (int i = 1; i <= n; i++)
{
    
    
    vis[i] = 0;
}
for (int i = 1; i <= n; i++)
{
    
    
    blocks[i] = cnt;

    if (tot == d)
    {
    
    
        tot = 1;
        cnt++;
    }
    else
    {
    
    
        tot++;
    }
}

for (int i = 1; i <= cnt; i++)
{
    
    
    blockvis[i] = blocksum[i] = blocksize[i] = 0;
}
for (int i = 1; i <= n; i++)
{
    
    
    blocksize[blocks[i]]++;
}

for (ll i = 1; i <= m; i++)
{
    
    
    if (blocks[nodes[i].l] == blocks[nodes[i].r])
    {
    
    
        if (blockvis[blocks[nodes[i].l]] != blocksize[blocks[nodes[i].l]])
        {
    
    
            for (ll j = nodes[i].l; j <= nodes[i].r; j++)
            {
    
    
            }
        }
    }
    else
    {
    
    
        if (blockvis[blocks[nodes[i].l]] != blocksize[blocks[nodes[i].l]])
        {
    
    
            for (ll j = nodes[i].l; blocks[j] == blocks[nodes[i].l]; j++)
            {
    
    
            }
        }
        if (blockvis[blocks[nodes[i].r]] != blocksize[blocks[nodes[i].r]])
        {
    
    
            for (ll j = nodes[i].r; blocks[j] == blocks[nodes[i].r]; j--)
            {
    
    
            }
        }
        for (ll j = blocks[nodes[i].l] + 1; j < blocks[nodes[i].r]; j++)
        {
    
    
        }
    }
}


ll t, ans;
ll blo[maxn];

int main()
{
    
    
    // DEBUG;
    scanf("%lld", &t);
    blo[0] = 5;
    ll block = 1e4;
    for (ll i = 1; i <= 1e5; i++)
    {
    
    
        blo[i] = (i + 1) * block;
    }

    while (t--)
    {
    
    
        ll L, R;
        scanf("%lld%lld", &L, &R);
        ll l = L / block + 1, r = R / block - 1;
        ll minn = INF;
        if (R - L <= 5 * block)
        {
    
    
            for (ll i = L; i <= R; i++)
            {
    
    
                
            }
            continue;
        }
        for (ll i = L; i <= l * block; i++)
        {
    
    
            
        }
        for (ll i = r * block + 1; i <= R; i++)
        {
    
    
            
        }
        // printf("*1\n");
        for (ll i = l; i <= r; i++)
        {
    
    
            
        }
    }
}

莫队
T(n): O((n+m)*sqrt(n))

ll n,q,blo,curl,curr,cnt[maxn],answer,ans[maxn];
ll arr[maxn];

struct Query
{
    
    
    ll l,r,pos;
    bool operator<(Query other)const
    {
    
    
        if(l/blo!=other.l/blo) return l<other.l;
        else return r<other.r;
    }
}qry[maxn];

void add(ll pos)
{
    
    
    cnt[arr[pos]]++;
    if(cnt[arr[pos]]==1) answer++;//每个题都不一样
}

void del(ll pos)
{
    
    
    cnt[arr[pos]]--;
    if(cnt[arr[pos]]==0) answer--;//每个题都不一样
}

int main()
{
    
    
    scanf("%lld%lld%lld", &n, &q, &k);
    blo = sqrt(n);
    for (ll i = 1; i <= n; i++)
    {
    
    
        scanf("%lld", &arr[i]);
    }
    for (ll i = 1; i <= q; i++)
    {
    
    
        ll l, r;
        scanf("%lld%lld", &l, &r);
        qry[i] = {
    
    l, r, i};
    }
    sort(qry + 1, qry + q + 1);
    curl=curr=1;
    cnt[arr[1]]++;
    sum+=cnt[arr[1]]*cnt[arr[1]];
    for (ll i = 1; i <= q; i++)
    {
    
    
        ll l = qry[i].l, r = qry[i].r;
        while (curl < l)
            del(curl++);
        while (curl > l)
            add(--curl);
        while (curr < r)
            add(++curr);
        while (curr > r)
            del(curr--);
        ans[qry[i].pos] = sum;
    }
    for (ll i = 1; i <= q; i++)
    {
    
    
        printf("%lld\n", ans[i]);
    }
}

带修莫队
T(n): O(n^(3/5)​)

ll n, q, blo, curl, curr, cnt[maxn], answer, ans[maxn], sum, k, xiu,now,qnum;
ll arr[maxn];

struct Query
{
    
    
    ll l, r, pos, xiu;
    bool operator<(Query other) const
    {
    
    
        if (l / blo != other.l / blo)
            return l < other.l;
        else if(r / blo != other.r / blo)
            return r < other.r;
        else return xiu<other.xiu;
    }
} qry[maxn];

struct Xiu
{
    
    
    ll pos,val;
}xs[maxn];

void add(ll pos)
{
    
    
    cnt[arr[pos]]++;
    if(cnt[arr[pos]]==1) sum++;
}

void del(ll pos)
{
    
    
    cnt[arr[pos]]--;
    if(cnt[arr[pos]]==0) sum--;
}

void work(ll now,ll l,ll r,ll x)
{
    
    
    if(xs[now].pos>=l&&xs[now].pos<=r)
    {
    
    
        cnt[arr[xs[now].pos]]--;
        if(cnt[arr[xs[now].pos]]==0) sum--;
        cnt[xs[now].val]++;
        if(cnt[xs[now].val]==1) sum++;
    }
    swap(arr[xs[now].pos],xs[now].val);
}

int main()
{
    
    
    // DEBUG;
    scanf("%lld%lld", &n, &q);
    blo = pow(n,2.0/3);
    for (ll i = 1; i <= n; i++)
    {
    
    
        scanf("%lld", &arr[i]);
    }
    for (ll i = 1; i <= q; i++)
    {
    
    
        char op[20];
        scanf("%s", op);
        if (op[0] == 'Q')
        {
    
    
            ll l, r;
            scanf("%lld%lld", &l, &r);
            qry[++qnum] = {
    
    l, r, qnum,xiu};
        }
        else
        {
    
    
            ll x,c;
            scanf("%lld%lld", &x, &c);
            xs[++xiu]={
    
    x,c};
        }
    }
    sort(qry + 1, qry + qnum + 1);
    curl = curr = 1,now=0;
    cnt[arr[1]]++;
    sum += cnt[arr[1]] * cnt[arr[1]];
    for (ll i = 1; i <= q; i++)
    {
    
    
        ll l = qry[i].l, r = qry[i].r,x=qry[i].xiu;
        while (curl < l)
            del(curl++);
        while (curl > l)
            add(--curl);
        while (curr < r)
            add(++curr);
        while (curr > r)
            del(curr--);
        while(now<x)
            work(++now,l,r,x);
        while(now>x)
            work(now--,l,r,x);
        ans[qry[i].pos]=sum;
    }
    for (ll i = 1; i <= qnum; i++)
    {
    
    
        printf("%lld\n", ans[i]);
    }
}

猜你喜欢

转载自blog.csdn.net/m0_51270992/article/details/120906443