您的位置:首页 > 其它

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

2016-03-17 18:04 375 查看
    【bzoj2120】数颜色

    暴力是不对的!!!

2014年4月26日1,0741

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;

                    
4000
    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;

        }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: