zoukankan      html  css  js  c++  java
  • P1903 [国家集训队]数颜色 / 维护队列 (带修莫队)

    题目描述

    墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会向你发布如下指令:

    1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。

    2、 R P Col 把第P支画笔替换为颜色Col。

    为了满足墨墨的要求,你知道你需要干什么了吗?

    输入格式

    第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数。

    第2行N个整数,分别代表初始画笔排中第i支画笔的颜色。

    第3行到第2+M行,每行分别代表墨墨会做的一件事情,格式见题干部分。

    输出格式

    对于每一个Query的询问,你需要在对应的行中给出一个数字,代表第L支画笔到第R支画笔中共有几种不同颜色的画笔。

    输入输出样例

    输入 #1
    6 5
    1 2 3 4 5 5
    Q 1 4
    Q 2 6
    R 1 2
    Q 1 4
    Q 2 6
    输出 #1
    4
    4
    3
    4
    

    说明/提示

    对于30%的数据,n,m leq 10000n,m10000

    对于60%的数据,n,m leq 50000n,m50000

    对于所有数据,n,m leq 133333n,m133333

    所有的输入数据中出现的所有整数均大于等于1且不超过10^6。

    本题可能轻微卡常数

    因为某些nt操作导致改了一天的bug, 所以记录一下 (不仔细读题的下场

    排序条件尽量用三元表达式, 避免使用if else if, 后者花的时间很可能是不可接受的

    举个例子, 上面是三元表达式排序, 下面是if else if判断排序, 时间差距甚至达到了一倍甚至更多

     

      1 #include <iostream>
      2 #include <algorithm>
      3 #include <climits>
      4 #include <cmath>
      5 using namespace std;
      6 constexpr int MAXN = 2e6 + 7, MAXM = 2e6 + 7, inf = 0x3f3f3f3f;
      7 typedef long long ll;
      8 int Block_Size, n, m;
      9 int a[MAXN], id[MAXN], color[MAXN], ans[MAXN], res, qc, mc, ls = 1, rs;
     10 
     11 inline int read()
     12 {
     13     char c = getchar();
     14     int x = 0, f = 1;
     15     while (c < '0' || c > '9')
     16     {
     17         if (c == '-')
     18             f = -1;
     19         c = getchar();
     20     }
     21     while (c >= '0' && c <= '9')
     22     {
     23         x = x * 10 + c - '0', c = getchar();
     24     }
     25     return x * f;
     26 }
     27 struct query
     28 {
     29     int l;
     30     int r;
     31     int qid;
     32     int time;
     33     query(int l = 0, int r = 0, int qid = 0, int time = 0) : l(l), r(r), qid(qid), time(time)
     34     {
     35     }
     36 
     37     bool operator<(const query &other) const
     38     {
     39         //一定要避免使用if else if的形式!!!!
     40         //例如下面的写法
     41 
     42         return id[l] == id[other.l] ? id[r] == id[other.r] ? time < other.time : r < other.r : l < other.l;
     43         // if (id[l] == id[other.l])
     44         // {
     45         //     if (id[r] == id[other.r])
     46         //         return l < other.l;
     47         //     return r < other.r;
     48         // }
     49         // return time < other.time;
     50     }
     51 } q[MAXM];
     52 
     53 struct modify
     54 {
     55     int pos;
     56     int val;
     57     modify(int pos = 0, int val = 0) : pos(pos), val(val)
     58     {
     59     }
     60 } mod[MAXM];
     61 
     62 void del(int val)
     63 {
     64     if (--color[val] == 0)
     65         --res;
     66 }
     67 
     68 void add(int val)
     69 {
     70     if (++color[val] == 1)
     71         ++res;
     72 }
     73 
     74 void update(int x, int i)
     75 {
     76     if (q[i].l <= mod[x].pos && mod[x].pos <= q[i].r)
     77     {
     78         del(a[mod[x].pos]);
     79         add(mod[x].val);
     80     }
     81     swap(a[mod[x].pos], mod[x].val);
     82 }
     83 
     84 int main()
     85 {
     86     char op;
     87     int l, r, now = 0;
     88     n = read();
     89     m = read();
     90     Block_Size = pow(n, 2.0 / 3.0);
     91     for (int i = 1; i <= n; ++i)
     92     {
     93         a[i] = read();
     94         id[i] = (i - 1) / Block_Size;
     95     }
     96 
     97     for (int i = 1; i <= m; ++i)
     98     {
     99         scanf("%c", &op);
    100         l = read();
    101         r = read();
    102         if (op == 'R')
    103         {
    104             ++mc;
    105             mod[mc].pos = l;
    106             mod[mc].val = r;
    107         }
    108         else
    109         {
    110             ++qc;
    111             q[qc].l = l;
    112             q[qc].r = r;
    113             q[qc].time = mc;
    114             q[qc].qid = qc;
    115         }
    116     }
    117     sort(q + 1, q + qc + 1);
    118 
    119     for (int i = 1; i <= qc; ++i)
    120     {
    121         while (ls < q[i].l)
    122             del(a[ls++]);
    123         while (ls > q[i].l)
    124             add(a[--ls]);
    125 
    126         while (rs < q[i].r)
    127             add(a[++rs]);
    128         while (rs > q[i].r)
    129             del(a[rs--]);
    130 
    131         while (now < q[i].time)
    132             update(++now, i);
    133         while (now > q[i].time)
    134             update(now--, i);
    135 
    136         ans[q[i].qid] = res;
    137     }
    138 
    139     for (int i = 1; i <= qc; ++i)
    140     {
    141         printf("%d
    ", ans[i]);
    142     }
    143 
    144     return 0;
    145 }
    AC code
  • 相关阅读:
    【ADO.NET基础-GridView】GridView的编辑、更新、取消、删除以及相关基础操作代码
    【ADO.NET基础-Session】Session的基本应用
    【ADO.NET基础-数据加密】第一篇(加密解密篇)
    【ADO.NET基础知识】SqlConnection、command、DataSet 、DataTable、dataAdapter
    3、Flask实战第3天:url_for使用
    2、Flask实战第2天:URL传参
    1、Flask实战第1天:第一个Flask程序
    第5天-表单
    第4天-表格
    第3天-DIV+CSS布局
  • 原文地址:https://www.cnblogs.com/daremo/p/15367838.html
Copyright © 2011-2022 走看看