zoukankan      html  css  js  c++  java
  • bzoj 2120

    2120: 数颜色

    Time Limit: 6 Sec  Memory Limit: 259 MB
    Submit: 6430  Solved: 2562
    [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

    代码:
    //注意到颜色范围只有1e6,修改操作不超过1000。分块,用pre[i]记录col[i]上一次出现的位置,每一块中的pre数组
    //从小到大排序,然后二分找到有几个的pre在询问区间的左端点的左边就是有几种数,两边的区间暴力找。修改时暴力
    //修改,更新pre,nex。
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int MAXN=10009;
    int n,m,B,cnt,block[MAXN],pre[MAXN],nex[MAXN],last[1000009],p[MAXN],col[MAXN];
    void resort(int x)
    {
        int l=(x-1)*B+1,r=min(n,x*B);
        for(int i=l;i<=r;i++) p[i]=pre[i];
        sort(p+l,p+r+1);
    }
    void build()
    {
        for(int i=1;i<=n;i++){
            scanf("%d",&col[i]);
            pre[i]=last[col[i]];
            if(last[col[i]]) nex[last[col[i]]]=i;
            last[col[i]]=i;
            block[i]=(i-1)/B+1;
        }
        for(int i=1;i<=cnt;i++) resort(i);
    }
    int find(int x,int ql)
    {
        int l=(x-1)*B+1,r=x*B,ans=0;
        int st=l;
        while(l<=r){
            int mid=(l+r)>>1;
            if(p[mid]<ql) { ans=mid-st+1;l=mid+1; }
            else r=mid-1;
        }
        return ans;
    }
    int query(int ql,int qr)
    {
        int s=0;
        for(int i=ql;i<=min(n,block[ql]*B);i++)
            if(pre[i]<ql) s++;
        if(block[ql]!=block[qr]){
            for(int i=(block[qr]-1)*B+1;i<=qr;i++)
                if(pre[i]<ql) s++;
        }
        for(int i=block[ql]+1;i<block[qr];i++) s+=find(i,ql);
        return s;
    }
    void update(int x,int y)
    {
        col[x]=y;
        if(nex[x]) { pre[nex[x]]=pre[x];resort(block[nex[x]]); }
        if(pre[x]) nex[pre[x]]=nex[x];
        int pr=0,ne=0;
        for(int i=x-1;i>=1;i--)
            if(col[i]==y) { pr=i;break; }
        for(int i=x+1;i<=n;i++)
            if(col[i]==y) { ne=i;break; }
        pre[x]=pr;nex[x]=ne;
        resort(block[x]);
        if(pr) nex[pr]=x;
        if(ne) { pre[ne]=x;resort(block[ne]); }
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        memset(last,0,sizeof(last));
        scanf("%d%d",&n,&m);
        B=sqrt(n);
        cnt=n/B+(n%B!=0);
        build();
        while(m--){
            char ch[3];
            int x,y;
            scanf("%s%d%d",ch,&x,&y);
            if(ch[0]=='Q') printf("%d
    ",query(x,y));
            else update(x,y);
        }
        return 0;
    }
  • 相关阅读:
    Google maps not working IE11
    谷歌地图插件
    杨辉三角python的最佳实现方式,牛的不能再牛了
    今日头条推荐算法原理全文详解
    项目启动大会要点
    学金融应该看的书籍
    【从0到1】经典语录
    appium学习链接记录
    Axure-计算输入字数
    如何提升个人专业能力
  • 原文地址:https://www.cnblogs.com/--ZHIYUAN/p/7896507.html
Copyright © 2011-2022 走看看