zoukankan      html  css  js  c++  java
  • 【BZOJ-2453&2120】维护队列&数颜色 分块 + 带修莫队算法

    2453: 维护队列

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 653  Solved: 283
    [Submit][Status][Discuss]

    Description

    你小时候玩过弹珠吗?
    小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N。为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少。当然,A有时候会依据个人喜好,替换队列中某个弹珠的颜色。但是A还没有学过编程,且觉得头脑风暴太浪费脑力了,所以向你来寻求帮助。

    Input

    输入文件第一行包含两个整数N和M。
    第二行N个整数,表示初始队列中弹珠的颜色。
    接下来M行,每行的形式为“Q L R”或“R x c”,“Q L R”表示A想知道从队列第L个弹珠到第R个弹珠中,一共有多少不同颜色的弹珠,“R x c”表示A把x位置上的弹珠换成了c颜色。

    Output

    对于每个Q操作,输出一行表示询问结果。

    Sample Input

    2 3
    1 2
    Q 1 2
    R 1 2
    Q 1 2

    Sample Output

    2
    1

    HINT

    对于100%的数据,有1 ≤ N ≤ 10000, 1 ≤ M ≤ 10000,小朋友A不会修改超过1000次,所有颜色均用1到10^6的整数表示。

    Source

    2011福建集训

    2120: 数颜色

    Time Limit: 6 Sec  Memory Limit: 259 MB
    Submit: 2845  Solved: 1105
    [Submit][Status][Discuss]

    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。

    2016.3.2新加数据两组by Nano_Ape

    Source

    Solution

    本来想练分块的,旁边的DCrusher爷,一眼爆正解莫队

    其实感觉这道题,分块,莫队,主席树都是可以A掉的,但是还是写了莫队

    很简单的带修改莫队,比昨天的糖果公园不知道简单到哪去了

    至于处理修改,处理出时间戳,在询问前时光倒流和后流,正常莫队就好

    Code

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    #define maxm 20010
    #define maxc 1000100
    int n,m,bll,ans[maxm],nl=1,nr=0,nt=0,an,pos[maxm],num[maxc],a[maxm],aa[maxm]; bool visit[maxc];
    struct Asknode
    {
        int l,r,t,id;
        bool operator < (const Asknode & A) const
            {
                if (pos[l]==pos[A.l] && pos[r]==pos[A.r]) return t<A.t;
                    else if (pos[l]==pos[A.l]) return r<A.r;
                        else return l<A.l; 
            }
    }q[maxm];int qn;
    struct Changenode{int x,c,t,pre;}ch[maxm];int cn;
    void move(int x)
    {
        if (visit[x])
            {num[a[x]]--;if (num[a[x]]==0) an--; visit[x]=0;}
        else 
            {num[a[x]]++;if (num[a[x]]==1) an++; visit[x]=1;}
    }
    void movedown(int T)
    {
        int x=ch[T].x,c=ch[T].c;
        if (visit[x])
            {num[a[x]]--; if (num[a[x]]==0) an--; a[x]=c; num[c]++; if (num[c]==1) an++;}
        else 
            a[x]=c;
    }
    void moveforward(int T)
    {
        int x=ch[T].x,c=ch[T].pre;
        if (visit[x])
            {num[a[x]]--; if (num[a[x]]==0) an--; a[x]=c; num[c]++; if (num[c]==1) an++;}
        else
            a[x]=c;
    }
    void work(int x)
    {
        int L=q[x].l,R=q[x].r,id=q[x].id,T=q[x].t;
        while (nl<L) move(nl),nl++;
        while (nl>L) nl--,move(nl);
        while (nr<R) nr++,move(nr);
        while (nr>R) move(nr),nr--;
        while (nt<T) nt++,movedown(nt);
        while (nt>T) moveforward(nt),nt--;
        ans[id]=an;
    }
    int main()
    {
        n=read(),m=read(); bll=int(sqrt(n));
        for (int i=1; i<=n; i++) aa[i]=a[i]=read(),pos[i]=(i-1)/bll+1;
        for (int i=1; i<=m; i++)
            {
                char opt[5]; scanf("%s",opt); int x=read(),y=read();
                if (opt[0]=='Q')
                    qn++,q[qn].id=qn,q[qn].l=x,q[qn].r=y,q[qn].t=cn;
                if (opt[0]=='R')
                    cn++,ch[cn].t=i,ch[cn].x=x,ch[cn].c=y,ch[cn].pre=aa[x],aa[x]=y;
            }
        sort(q+1,q+qn+1);
        for (int i=1; i<=qn; i++) work(i);
        for (int i=1; i<=qn; i++) printf("%d
    ",ans[i]);
        return 0;
    }

    虽然DCrusher爷一样爆正解,但我觉得他不能轻视1A...

  • 相关阅读:
    git commit --amend
    webpack代码分割
    selection And range js
    自动化测试
    python学习路线图
    Java--解决JDK14没有jre问题
    Java-win下环境变量设置
    Jenkins忘记admin密码拯救方法
    Windows或linux下 pip设置默认豆瓣镜像源
    ChromeDriver与Chrome版本对应参照表及ChromeDriver下载链接
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5437451.html
Copyright © 2011-2022 走看看