zoukankan      html  css  js  c++  java
  • [bzoj2120][数颜色] (暴力 or 分块)

    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

    Solution

    先上简单的暴力,可以水过

    #include <stdio.h>
    #include <string.h>
    #define M 1000010
    
    inline int Rin() {
        int x=0,c=getchar(),f=1;
        for(; c<48||c>57; c=getchar())
            if(c==45)f=-1;
        for(; c>47&&c<58; c=getchar())
            x=(x<<1)+(x<<3)+c-48;
        return x*f; }
    
    char c;
    int g[M],n,m,a[M],top,x,y,i,mark[M],ans;
    
    int main() {
        n=Rin(),m=Rin();
        for(i=1; i<=n; i++) {
            a[i]=Rin();
            if(!g[a[i]])
                g[a[i]]=++top;
            a[i]=g[a[i]]; }
        while(m--) {
            do c=getchar(); while(c!='Q'&&c!='R');
            x=Rin(),y=Rin();
            if(c=='Q') {
                for(i=x,ans=0; i<=y; i++)
                    if(mark[a[i]]!=m)
                        mark[a[i]]=m,ans++;
                printf("%d
    ",ans);
            }
            else {
                if(!g[y])g[y]=++top;
                a[x]=g[y];
            }
        }
        return 0;
    }

     一下是莫队的做法

    otz menci

    #include <math.h>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #define N 10010
    #define M 1000010
    #define RG register
    #define inline __inline__ __attribute__((always_inline))
    
    inline void Rin(RG int &x) {
        x=0;RG int c=getchar(),f=1;
        for(; c<48||c>57; c=getchar())
            if(c==45)f=-1;
        for(; c>47&&c<58; c=getchar())
            x=(x<<1)+(x<<3)+c-48;
        x*=f; }
    
    int n,m,block_size,a[N],utop,qtop,ans[N],cnt[M];
    
    struct Update {
        int pos,eld,now; }U[N];
    
    struct Request{
        int tim,l,r,id;
    
        bool operator < (const Request &other)const {
            if(l/block_size == other.l/block_size) {
                if(r/block_size == other.r/block_size)
                    return tim < other.tim;
                return r/block_size < other.r/block_size; }
            return l/block_size < other.l/block_size; } }Q[N];
    
    inline void prepare() {
        static int nowlist[N];
        memcpy(nowlist,a,sizeof a);
        for(RG int i=1; i<=utop; i++) {
            U[i].eld=nowlist[U[i].pos];
            nowlist[U[i].pos]=U[i].now; } }
    
    inline void extend(RG int &tmp,RG int pos,RG int dir) {
        if(dir == 1) {
            if(++cnt[a[pos]]==1)
                tmp++; }
        else
            if(--cnt[a[pos]]==0)
                tmp--; }
    
    inline void modify(RG int &tmp,RG int T,RG int l,RG int r,RG int dir) {
        RG Update x=U[T];
        if(dir == 1) {
            a[x.pos]=x.now;
            if(x.pos >=l && x.pos <= r) {
                if(--cnt[x.eld]==0)tmp--;
                if(++cnt[x.now]==1)tmp++; } }
        else {
            if(x.pos >=l && x.pos <= r) {
                if(--cnt[x.now]==0)tmp--;
                if(++cnt[x.eld]==1)tmp++; }
            a[x.pos]=x.eld; } }
    
    inline void block_solve() {
        for(RG int l=1,r=0,ans=0,T=0,i=1; i<=qtop; i++) {
            while(r < Q[i].r)extend(ans,++r,1);
            while(r > Q[i].r)extend(ans,r--,-1);
    
            while(l > Q[i].l)extend(ans,--l,1);
            while(l < Q[i].l)extend(ans,l++,-1);
    
            while(T < Q[i].tim)modify(ans,++T,l,r,1);
            while(T > Q[i].tim)modify(ans,T--,l,r,-1);
            :: ans[Q[i].id]=ans; } }
    
    int main() {
    
        Rin(n),Rin(m);
        for(RG int i=1; i<=n; i++)
            Rin(a[i]);
        for(RG int i=1; i<=m; i++) {
            RG char c;
            do c=getchar(); while(c != 'Q'&&c != 'R');
            if(c == 'Q') {
                ++qtop;
                Rin(Q[qtop].l),Rin(Q[qtop].r);
                Q[qtop].id=qtop;
                Q[qtop].tim=utop; }
            else {
                ++utop;
                Rin(U[utop].pos),Rin(U[utop].now); } }
    
        prepare();
        block_size=floor(pow(n,2.0/3)+1);
        std::sort(Q+1,Q+1+qtop);
        block_solve();
    
        for(RG int i=1; i<=qtop;i++)
            printf("%d
    ",ans[i]);
        return 0; }
  • 相关阅读:
    RAID技术
    Mysql的用户基本操作
    LNMP之Php的安装配置
    java 实现图片拼接
    java 实现Serv-U FTP 和 SFTP 上传 下载
    Image合并添加文字内容
    AOP切面用于系统日志
    网页评论实现
    java web 实体类生成
    java接口调试思想
  • 原文地址:https://www.cnblogs.com/keshuqi/p/6288460.html
Copyright © 2011-2022 走看看