bzoj 2120 数颜色 莫队超级大暴力

    【bzoj2120】数颜色



    暴力是不对的!!!

2014年4月26日 1,074 1

Description

墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会像你发布如下指令: 1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。 2、 R P Col 把第P支画笔替换为颜色Col。为了满足墨墨的要求,你知道你需要干什么了吗?

Input

第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数。第2行N个整数,分别代表初始画笔排中第i支画笔的颜色。第3行到第2+M行,每行分别代表墨墨会做的一件事情,格式见题干部分。

Output

对于每一个Query的询问,你需要在对应的行中给出一个数字,代表第L支画笔到第R支画笔中共有几种不同颜色的画笔。

Sample Input

6 5
1 2 3 4 5 5
Q 1 4
Q 2 6
R 1 2
Q 1 4
Q 2 6

Sample Output

4
4
3
4

HINT

对于100%的数据,N≤10000,M≤10000,修改操作不多于1000次,所有的输入数据中出现的所有整数均大于等于1且不超过10^6。


我们用离线莫队先求出没有修改时的答案,再暴力枚举修改操作,如果修改操作在查询区间内并且在询问操作之前,那么重新修改答案


网上题解太扯淡,请大家相信暴力(但要记住,暴力是不对的):



#include<iostream>
#include<string.h>
#include<stdio.h>
#include<vector>
#include<math.h>
#include<algorithm>
#define ll long long
#define maxx 100010
using namespace std;
struct ask{int l;int r;int dev;int mark;int a;} cha[maxx/10];
struct qq{int pos;int num;int mark;};
vector<qq> gai;
int whe=0;
int n,m;
int a,b,c,d;
int zu[maxx/10];
int cmp(ask aa,ask bb)
{
        if (aa.dev!=bb.dev)
                return aa.dev<bb.dev;
        return aa.r<bb.r;

}
int arr[maxx];
int tzu[maxx/10];
int tarr[maxx];
int aa[maxx];

int bb[maxx];
int main()
{
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++)
                scanf("%d",&zu[i]);
        char cc;

        for (int i=1;i<=m;i++)
        {
               cin>>cc;
                if (cc=='Q')
                {
                        scanf("%d%d",&a,&b);
                        ask zz;
                        zz.l=a;
                        zz.r=b;
                        zz.mark=i;
                        cha[++whe]=zz;

                }
                if (cc=='R')
                {
                        scanf("%d%d",&a,&b);
                        qq ss;
                        ss.pos=a;
                        ss.num=b;
                        ss.mark=i;
                        gai.push_back(ss);
                }
        }



        a=sqrt(whe);
        for (int i=1;i<=whe;i++)
        {
                cha[i].dev=i/a+1;
        }
        sort(cha+1,cha+1+whe,cmp);

     //   for (int i=1;i<=whe;i++)
                //cout<<cha[i].dev<<"   is dev   &&   l is  "<<cha[i].l<<"    r is   "<<cha[i].r<<"  mark is  "<<cha[i].mark<<endl;










        int nowl=0,nowr=0;
        int ans=0;
        memset(arr,0,sizeof(arr));



        for (int ss=1;ss<=whe;ss++)
        {
                ask now;
                now=cha[ss];
                while(nowl<now.l)
                {
                        bb[zu[nowl]]--;
                        if (bb[zu[nowl]]==0)
                                ans--;
                        nowl++;
                }
                while(nowl>now.l)
                {
                        a=nowl-1;
                        bb[zu[a]]++;
                        if (bb[zu[a]]==1)
                                ans++;
                        nowl--;
                }
                while(nowr<now.r)
                {
                        a=nowr+1;
                        bb[zu[a]]++;
                        if (bb[zu[a]]==1)
                                ans++;
                        nowr++;
                }
                while(nowr>now.r)
                {
                        bb[zu[nowr]]--;
                        if (bb[zu[nowr]]==0)
                                ans--;
                        nowr--;
                }
                a=ans;
                for (int i=1;i<maxx;i++)
                        tzu[i]=zu[i];
                for (int i=1;i<=maxx;i++)
                        aa[i]=bb[i];


                for (int i=0;i<gai.size();i++)
                {

                        if (gai[i].mark<cha[ss].mark && gai[i].pos<=cha[ss].r && gai[i].pos>=cha[ss].l)
                        {

                                aa[tzu[gai[i].pos]]--;

                                if (aa[tzu[gai[i].pos]]==0)      a--;
                                tzu[gai[i].pos]=gai[i].num;
                        }
                }
              //  if (ss==2)
                      //  for (int i=1;i<=10;i++)
                          //cout<<bb[i]<<"  ";
                cout<<a<<endl;
        }
}












猜你喜欢

转载自blog.csdn.net/williamcode/article/details/50915854