zoukankan      html  css  js  c++  java
  • BZOJ2120 数颜色 —— 待修改莫队

    题目链接:https://vjudge.net/problem/HYSBZ-2120

    2120: 数颜色

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

    题意:

    查询区间颜色种数,且带修改。

    代码如下:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <vector>
      6 #include <cmath>
      7 #include <queue>
      8 #include <stack>
      9 #include <map>
     10 #include <string>
     11 #include <set>
     12 using namespace std;
     13 typedef long long LL;
     14 const int INF = 2e9;
     15 const LL LNF = 9e18;
     16 const int MOD = 1e9+7;
     17 const int MAXN = 1e6+10;
     18 
     19 int val[MAXN], tmp[MAXN];
     20 int block, sum[MAXN], Ans[MAXN];
     21 int num1, num2;
     22 
     23 struct Node
     24 {
     25     //index记录查询的编号, t记录查询时执行了多少步修改
     26     int l, r, index, t;
     27     bool operator<(const Node&x) const{
     28         if(l/block!=x.l/block) return l/block<x.l/block;
     29         else if(r!=x.r) return r<x.r;
     30         else return  t<x.t;
     31     }
     32 }q[MAXN];
     33 
     34 struct
     35 {
     36     //preCol记录修改前pos位的颜色, nowCol记录修改后pos位的颜色
     37     int pos, nowCol, preCol;
     38 }op[MAXN];
     39 
     40 int L, R, T, ans;
     41 void modifyTime(int pos, int col)
     42 {
     43     if(L<=pos && pos<=R)
     44     {
     45         sum[val[pos]]--;
     46         if(sum[val[pos]]==0) ans--;
     47         val[pos] = col;
     48         sum[val[pos]]++;
     49         if(sum[val[pos]]==1) ans++;
     50     }
     51     else val[pos] = col;
     52 }
     53 
     54 void add(int pos)
     55 {
     56     sum[val[pos]]++;
     57     if(sum[val[pos]]==1) ans++;
     58 }
     59 
     60 void del(int pos)
     61 {
     62     sum[val[pos]]--;
     63     if(sum[val[pos]]==0) ans--;
     64 }
     65 
     66 void work()
     67 {
     68     L = 1, R = 0, T = 0, ans = 0;
     69     memset(sum, 0, sizeof(sum));
     70     for(int i = 1; i<=num1; i++)
     71     {
     72         while(T<q[i].t) T++, modifyTime(op[T].pos, op[T].nowCol);
     73         while(T>q[i].t) modifyTime(op[T].pos, op[T].preCol), T--;
     74         while(L<q[i].l) del(L), L++;
     75         while(L>q[i].l) L--, add(L);
     76         while(R<q[i].r) R++, add(R);
     77         while(R>q[i].r) del(R), R--;
     78         Ans[q[i].index] = ans;
     79     }
     80 }
     81 
     82 int main()
     83 {
     84     int n, m;
     85     while(scanf("%d%d", &n,&m)!=EOF)
     86     {
     87         block = sqrt(n);
     88         for(int i = 1; i<=n; i++)
     89         {
     90             scanf("%d", &val[i]);
     91             tmp[i] = val[i];
     92         }
     93 
     94         num1 = num2 = 0;
     95         for(int i = 1; i<=m; i++)
     96         {
     97             char s[2]; int x, y;
     98             scanf("%s%d%d", s, &x, &y);
     99             if(s[0]=='Q')
    100             {
    101                 q[++num1].index = num1;
    102                 q[num1].t = num2;
    103                 q[num1].l = x;
    104                 q[num1].r = y;
    105             }
    106             else    //tmp用于记录动态修改时每个位置上的颜色
    107             {
    108                 op[++num2].pos = x;
    109                 op[num2].nowCol = y;
    110                 op[num2].preCol = tmp[x];
    111                 tmp[x] = y;
    112             }
    113         }
    114 
    115         sort(q+1, q+1+num1);
    116         work();
    117         for(int i = 1; i<=num1; i++)
    118             printf("%d
    ", Ans[i]);
    119     }
    120 }
    View Code

    直接暴力也行:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <vector>
      6 #include <cmath>
      7 #include <queue>
      8 #include <stack>
      9 #include <map>
     10 #include <string>
     11 #include <set>
     12 using namespace std;
     13 typedef long long LL;
     14 const int INF = 2e9;
     15 const LL LNF = 9e18;
     16 const int MOD = 1e9+7;
     17 const int MAXN = 1e6+10;
     18 
     19 int val[MAXN], tmp[MAXN];
     20 int block, sum[MAXN], Ans[MAXN];
     21 int num1, num2;
     22 
     23 struct Node
     24 {
     25     //index记录查询的编号, t记录查询时执行了多少步修改
     26     int l, r, index, t;
     27 }q[MAXN];
     28 
     29 struct
     30 {
     31     //preCol记录修改前pos位的颜色, nowCol记录修改后pos位的颜色
     32     int pos, nowCol, preCol;
     33 }op[MAXN];
     34 
     35 int L, R, T, ans;
     36 void modifyTime(int pos, int col)
     37 {
     38     if(L<=pos && pos<=R)
     39     {
     40         sum[val[pos]]--;
     41         if(sum[val[pos]]==0) ans--;
     42         val[pos] = col;
     43         sum[val[pos]]++;
     44         if(sum[val[pos]]==1) ans++;
     45     }
     46     else val[pos] = col;
     47 }
     48 
     49 void add(int pos)
     50 {
     51     sum[val[pos]]++;
     52     if(sum[val[pos]]==1) ans++;
     53 }
     54 
     55 void del(int pos)
     56 {
     57     sum[val[pos]]--;
     58     if(sum[val[pos]]==0) ans--;
     59 }
     60 
     61 void work()
     62 {
     63     L = 1, R = 0, T = 0, ans = 0;
     64     memset(sum, 0, sizeof(sum));
     65     for(int i = 1; i<=num1; i++)
     66     {
     67         while(T<q[i].t) T++, modifyTime(op[T].pos, op[T].nowCol);
     68         while(T>q[i].t) modifyTime(op[T].pos, op[T].preCol), T--;
     69         while(L<q[i].l) del(L), L++;
     70         while(L>q[i].l) L--, add(L);
     71         while(R<q[i].r) R++, add(R);
     72         while(R>q[i].r) del(R), R--;
     73         Ans[q[i].index] = ans;
     74     }
     75 }
     76 
     77 int main()
     78 {
     79     int n, m;
     80     while(scanf("%d%d", &n,&m)!=EOF)
     81     {
     82         for(int i = 1; i<=n; i++)
     83         {
     84             scanf("%d", &val[i]);
     85             tmp[i] = val[i];
     86         }
     87 
     88         num1 = num2 = 0;
     89         for(int i = 1; i<=m; i++)
     90         {
     91             char s[2]; int x, y;
     92             scanf("%s%d%d", s, &x, &y);
     93             if(s[0]=='Q')
     94             {
     95                 q[++num1].index = num1;
     96                 q[num1].t = num2;
     97                 q[num1].l = x;
     98                 q[num1].r = y;
     99             }
    100             else    //tmp用于记录动态修改时每个位置上的颜色
    101             {
    102                 op[++num2].pos = x;
    103                 op[num2].nowCol = y;
    104                 op[num2].preCol = tmp[x];
    105                 tmp[x] = y;
    106             }
    107         }
    108 
    109         work();
    110         for(int i = 1; i<=num1; i++)
    111             printf("%d
    ", Ans[i]);
    112     }
    113 }
    View Code
  • 相关阅读:
    Mac系统下安装和卸载HomeBrew的方法
    .NET笔试题集(五)
    .NET笔试题集(四)
    .NET笔试题集(二)
    .NET笔试题集(三)
    .NET笔试题集(一)
    C# 文件操作方法
    MD5 加密的两种方法
    jquery 元素选择器集合
    Jquery元素追加和删除
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/8321389.html
Copyright © 2011-2022 走看看