Goodbye Souvenir CodeForces - 849E

http://codeforces.com/problemset/problem/849/E

两种操作 一种是把p位置的颜色换为x 另一种是查询[l,r]内每种颜色出现位置的最大下标与最小下标之差的和

操作的先后次序作为第一维 每种颜色的当前位置作为第二维 上一次出现的位置作为第三维 前后位置之差作为加值 进行cdq分治 这样查询操作就转换为查询矩阵之和了

还有就是颜色的插入和删除比较麻烦 怎么苟怎么写就好

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

struct node1
{
    int tp;
    int x;
    int y;
    int val;
};

struct node2
{
    int l;
    int r;
    ll val;
};

set <int> st[100010];
node1 order[1000010],tmp[1000010];
node2 tree[400010];
int ary[100010];
ll ans[100010];
int n,q,tot;

void build(int l,int r,int cur)
{
    int m;
    tree[cur].l=l;
    tree[cur].r=r;
    tree[cur].val=0;
    if(l==r) return;
    m=(l+r)/2;
    build(l,m,2*cur);
    build(m+1,r,2*cur+1);
}

void update(int tar,int val,int cur)
{
    tree[cur].val+=val;
    if(tree[cur].l==tree[cur].r) return;
    if(tar<=tree[2*cur].r) update(tar,val,2*cur);
    else update(tar,val,2*cur+1);
}

ll query(int pl,int pr,int cur)
{
    ll res;
    if(pl<=tree[cur].l&&tree[cur].r<=pr) return tree[cur].val;
    res=0;
    if(pl<=tree[2*cur].r) res+=query(pl,pr,2*cur);
    if(pr>=tree[2*cur+1].l) res+=query(pl,pr,2*cur+1);
    return res;
}

void cdq(int l,int r)
{
    int m,p,q,cnt,i;
    if(l==r) return;
    m=(l+r)/2;
    cdq(l,m);
    cdq(m+1,r);
    p=l,q=m+1,cnt=l;
    while(p<=m&&q<=r)
    {
        if(order[p].x<=order[q].x)
        {
            if(order[p].tp==1) update(order[p].y,order[p].val,1);
            tmp[cnt++]=order[p++];
        }
        else
        {
            if(order[q].tp==2) ans[order[q].val]-=query(1,order[q].y,1);
            else if(order[q].tp==3) ans[order[q].val]+=query(1,order[q].y,1);
            tmp[cnt++]=order[q++];
        }
    }
    while(q<=r)
    {
        if(order[q].tp==2) ans[order[q].val]-=query(1,order[q].y,1);
        else if(order[q].tp==3) ans[order[q].val]+=query(1,order[q].y,1);
        tmp[cnt++]=order[q++];
    }
    for(i=l;i<p;i++)
    {
        if(order[i].tp==1) update(order[i].y,-order[i].val,1);
    }
    while(p<=m) tmp[cnt++]=order[p++];
    for(i=l;i<=r;i++) order[i]=tmp[i];
}

int main()
{
    set <int> ::iterator it;
    int i,op,p,x,l,r,p1,p2,cnt;
    scanf("%d%d",&n,&q);
    tot=0;
    for(i=1;i<=n;i++)
    {
        scanf("%d",&ary[i]);
        if(st[ary[i]].empty()) st[ary[i]].insert(i);
        else
        {
            st[ary[i]].insert(i);
            it=st[ary[i]].lower_bound(i);
            it--;
            tot++;
            order[tot].tp=1,order[tot].x=i,order[tot].y=(*it),order[tot].val=i-(*it);
        }
    }
    cnt=0;
    while(q--)
    {
        scanf("%d",&op);
        if(op==1)
        {
            scanf("%d%d",&p,&x);
            it=st[ary[p]].lower_bound(p);
            if(it!=st[ary[p]].begin())
            {
                it--;
                p1=(*it);
                it++;

                tot++;
                order[tot].tp=1,order[tot].x=p,order[tot].y=p1,order[tot].val=-(p-p1);

                it++;
                if(it!=st[ary[p]].end())
                {
                    p2=(*it);
                    tot++;
                    order[tot].tp=1,order[tot].x=p2,order[tot].y=p,order[tot].val=-(p2-p);
                    tot++;
                    order[tot].tp=1,order[tot].x=p2,order[tot].y=p1,order[tot].val=p2-p1;
                }
            }
            else
            {
                it++;
                if(it!=st[ary[p]].end())
                {
                    p2=(*it);
                    tot++;
                    order[tot].tp=1,order[tot].x=p2,order[tot].y=p,order[tot].val=-(p2-p);
                }
            }

            st[ary[p]].erase(p);
            st[x].insert(p);
            ary[p]=x;

            it=st[x].lower_bound(p);
            if(it!=st[x].begin())
            {
                it--;
                p1=(*it);
                it++;

                tot++;
                order[tot].tp=1,order[tot].x=p,order[tot].y=p1,order[tot].val=p-p1;

                it++;
                if(it!=st[x].end())
                {
                    p2=(*it);
                    tot++;
                    order[tot].tp=1,order[tot].x=p2,order[tot].y=p,order[tot].val=p2-p;
                    tot++;
                    order[tot].tp=1,order[tot].x=p2,order[tot].y=p1,order[tot].val=-(p2-p1);
                }
            }
            else
            {
                it++;
                if(it!=st[x].end())
                {
                    p2=(*it);
                    tot++;
                    order[tot].tp=1,order[tot].x=p2,order[tot].y=p,order[tot].val=p2-p;
                }
            }
        }
        else
        {
            scanf("%d%d",&l,&r);
            cnt++;
            if(l-1>=1)
            {
                tot++;
                order[tot].tp=2,order[tot].x=l-1,order[tot].y=r,order[tot].val=cnt;
                tot++;
                order[tot].tp=2,order[tot].x=r,order[tot].y=l-1,order[tot].val=cnt;
                tot++;
                order[tot].tp=3,order[tot].x=l-1,order[tot].y=l-1,order[tot].val=cnt;
            }
            tot++;
            order[tot].tp=3,order[tot].x=r,order[tot].y=r,order[tot].val=cnt;
        }
    }
    build(1,n,1);
    cdq(1,tot);
    for(i=1;i<=cnt;i++) printf("%lld\n",ans[i]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sunyutian1998/article/details/82019779