2120: 数颜色

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

 

[Submit][Status][Discuss]

这真是一道好题,貌似有好多种不同的做法。有人用树套树过的,有人用整体二分过的,有人用带修莫队过的,还有像我一样的蒟蒻用常数优化暴力过的。

虽然2016有新加数据,然而依然卡不住暴力,23333。

RunID User Problem Result Memory Time Language Code_Length Submit_Time
1734100 YOUSIKI 2120 Accepted 34496 kb 2340 ms C++/Edit 1411 B 2016-12-11 12:45:43
 #include <bits/stdc++.h>

 const int siz = ;

 char buf[siz], *bit = buf;

 inline int nextInt (void) {
register int ret = ;
register int neg = ; while (*bit < '')
if (*bit++ == '-')
neg ^= true; while (*bit >= '')
ret = ret* + *bit++ - ''; return neg ? -ret : ret;
} inline char nextChar (void) {
while (*bit != 'Q' && *bit != 'R')++bit;
return *bit ++;
} const int maxn = + ; int n, m;
int cases;
int total;
int answer;
int col[maxn];
int map[maxn];
int vis[maxn]; signed main (void) {
fread (buf, , siz, stdin); n = nextInt ();
m = nextInt (); for (register int i = ; i <= n; ++i) {
int color = nextInt ();
if (map[color] == )
map[color] = ++total;
col[i] = map[color];
} for (register int i = ; i <= n; ++i) {
switch (nextChar ()) {
case 'R' : {
int a = nextInt ();
int b = nextInt ();
if (map[b] == )
map[b] = ++total;
col[a] = map[b];
break;
}
case 'Q' : {
int a = nextInt ();
int b = nextInt ();
answer = , ++cases;
for (register int j = a; j <= b; ++j)
if (vis[col[j]] != cases)++answer, vis[col[j]] = cases;
printf("%d\n", answer);
}
}
}
}

然而不太理解为啥离散化一下就有这么大的用处。

RunID User Problem Result Memory Time Language Code_Length Submit_Time
1734122 YOUSIKI 2120 Time_Limit_Exceed 26684 kb 7632 ms C++/Edit 1289 B 2016-12-11 13:00:40
 #include <bits/stdc++.h>

 const int siz = ;

 char buf[siz], *bit = buf;

 inline int nextInt (void) {
register int ret = ;
register int neg = ; while (*bit < '')
if (*bit++ == '-')
neg ^= true; while (*bit >= '')
ret = ret* + *bit++ - ''; return neg ? -ret : ret;
} inline char nextChar (void) {
while (*bit != 'Q' && *bit != 'R')++bit;
return *bit ++;
} const int maxn = + ; int n, m;
int cases;
int answer;
int col[maxn];
int vis[maxn]; signed main (void) {
fread (buf, , siz, stdin); n = nextInt ();
m = nextInt (); for (register int i = ; i <= n; ++i)
col[i] = nextInt (); for (register int i = ; i <= m; ++i) {
switch (nextChar ()) {
case 'R' : {
int a = nextInt ();
int b = nextInt ();
col[a] = b;
break;
}
case 'Q' : {
int a = nextInt ();
int b = nextInt ();
answer = , ++cases;
for (register int j = a; j <= b; ++j)
if (vis[col[j]] != cases)++answer, vis[col[j]] = cases;
printf ("%d\n", answer);
}
}
}
}

当然,小生来写这道题不是为了练习暴力的,是为了学习带修莫队的。

有别于普通的莫队,带修莫队多了一维对时间的要求,每个询问可以表示为[l,r,t],表示区间需要我们维护到区间[l,r]在时刻t的存在情况。方法是,对于l,r还按照普通莫队的对l分组方式分组,组内对r排序,转移的时候暴力调整时间即可。貌似为了达到最优秀的复杂度,分组时的大小需要调整一下,但这题显然没有那么苛刻啦,o(* ̄▽ ̄*)ブ

 #include <bits/stdc++.h>

 const int siz = ;

 char buf[siz], *bit = buf;

 inline int nextInt (void) {
register int ret = ;
register int neg = ; while (*bit < '')
if (*bit++ == '-')
neg ^= true; while (*bit >= '')
ret = ret* + *bit++ - ''; return neg ? -ret : ret;
} inline char nextChar (void) {
while (*bit != 'Q' && *bit != 'R')++bit;
return *bit ++;
} const int maxn = + ;
const int maxm = + ; int n, m;
int l, r;
int s, t;
int answer;
int col[maxn];
int vis[maxm]; struct query {
int l, r, id, ans;
}qry[maxn]; int q; struct change {
int p, a, b, id;
}chg[maxn]; int c; inline bool cmp_lr (const query &A, const query &B) {
if (A.l / s != B.l / s)
return A.l < B.l;
else
return A.r < B.r;
} inline bool cmp_id (const query &A, const query &B) {
return A.id < B.id;
} inline void removeColor (int c) {
if (--vis[c] == )--answer;
} inline void insertColor (int c) {
if (++vis[c] == )++answer;
} inline void removeChange (change &c) {
col[c.p] = c.a;
if (c.p >= l && c.p <= r) {
removeColor(c.b);
insertColor(c.a);
}
} inline void insertChange (change &c) {
col[c.p] = c.b;
if (c.p >= l && c.p <= r) {
removeColor(c.a);
insertColor(c.b);
}
} inline void solve (query &q) {
while (t > && chg[t].id > q.id)
removeChange (chg[t--]);
while (t < c && chg[t + ].id < q.id)
insertChange (chg[++t]); while (l < q.l)removeColor (col[l++]);
while (l > q.l)insertColor (col[--l]);
while (r < q.r)insertColor (col[++r]);
while (r > q.r)removeColor (col[r--]); q.ans = answer;
} signed main (void) {
fread (buf, , siz, stdin); n = nextInt ();
m = nextInt (); for (register int i = ; i <= n; ++i)
col[i] = nextInt (); for (register int i = ; i <= m; ++i) {
switch (nextChar ()) {
case 'R' : {
chg[++c].id = i;
chg[c].p = nextInt ();
chg[c].b = nextInt ();
chg[c].a = col[chg[c].p];
col[chg[c].p] = chg[c].b;
break;
}
case 'Q' : {
qry[++q].id = i;
qry[q].l = nextInt ();
qry[q].r = nextInt ();
}
}
} s = sqrt (n); t = c; answer = ; l = ; r = ; std::sort (qry + , qry + + q, cmp_lr); for (register int i = ; i <= q; ++i)solve(qry[i]); std::sort (qry + , qry + + q, cmp_id); for (register int i = ; i <= q; ++i)
printf ("%d\n", qry[i].ans);
}

@Author: YouSiki

BZOJ 2120: 数颜色的更多相关文章

  1. BZOJ 2120 数颜色(带修改的莫队)

    2120: 数颜色 Time Limit: 6 Sec  Memory Limit: 259 MB Submit: 3478  Solved: 1342 [Submit][Status][Discus ...

  2. BZOJ 2120: 数颜色 分块

    2120: 数颜色 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php? ...

  3. Bzoj 2120: 数颜色 && 2453: 维护队列 莫队,分块,bitset

    2120: 数颜色 Time Limit: 6 Sec  Memory Limit: 259 MBSubmit: 2645  Solved: 1039[Submit][Status][Discuss] ...

  4. BZOJ 2120 数颜色 (带修莫队)

    2120: 数颜色 Time Limit: 6 Sec  Memory Limit: 259 MBSubmit: 6367  Solved: 2537[Submit][Status][Discuss] ...

  5. BZOJ 2120 数颜色 【带修改莫队】

    任意门:https://www.lydsy.com/JudgeOnline/problem.php?id=2120 2120: 数颜色 Time Limit: 6 Sec  Memory Limit: ...

  6. bzoj 2120 数颜色 题解

    转载请注明:http://blog.csdn.net/jiangshibiao/article/details/23990489 [原题] 2120: 数颜色 Time Limit: 6 Sec  M ...

  7. bzoj 2120 数颜色 (带修莫队)

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2120 题意:两种操作:Q 询问区间  l - r  内颜色的种类 ,R 单点修改 思路 ...

  8. BZOJ 2120 数颜色(带修改莫队)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2120 [题目大意] 给出一颜色序列,每次可以修改一个位置的颜色或者询问一个区间不同颜色 ...

  9. BZOJ 2120 数颜色&2453 维护队列 [带修改的莫队算法]【学习笔记】

    2120: 数颜色 Time Limit: 6 Sec  Memory Limit: 259 MBSubmit: 3665  Solved: 1422[Submit][Status][Discuss] ...

随机推荐

  1. iOS 学习 - 17.Socket

    Socket 是应用层与 TCP / IP 协议通信的中间软件抽象层,它是一组接口   TCP:面向连接.传输可靠(保证数据正确性,保证数据顺序).用于传输大量数据(流模式).速度慢,建立连接需要开销 ...

  2. Starling中通过PivotX 和 PivotY 修改原点

    一个显示对象的默认原点在左上角.addChild 是将它的左上角放在了父容器的(0, 0)位置. 如果将该显示对象的PivotX 和 PivotY 修改为其宽高的一半,那么它的原点就变到了该对象的中心 ...

  3. SQL SERVER特殊行转列案列一则

    今天有个同事找我,他说他有个需求,需要进行行转列,但是又跟一般的行转列有些区别,具体需求如下所说,需要将表1的数据转换为表2的显示格式. 我想了一下,给出了一个解决方法,具体如下所示(先给出测试数据) ...

  4. JVM之PC寄存器(Program Counter Register)

    基本特性: 当前线程执行的字节码的行号指示器. Java虚拟机支持多个线程同时执行,每一个线程都有自己的pc寄存器. 任意时刻,一个线程都只会执行一个方法的代码,称为该线程的当前方法,对于非nativ ...

  5. 查看C#的dll所依赖.Net版本

    Microsoft SDK自带的ildasm.exe工具, 是一个反编译工具, 可以查看编译好后的dll的文件 双击ildasm.exe, 把你要识别的.dll文件拖进来, 就会反编译了. 接着在il ...

  6. Linux 服务器模型小结

    当我们用socket进行编程的时候,细节上都是选择一个AF_LOCAL,AF_INET再根据相应的类型填充地址,其实根据通信需求,有几种简单的服务模型可供选用,掌握了这些框架再结合socket高度的抽 ...

  7. 2015.1.25 Delphi打开网址链接的几种方法

    Delphi打开网址链接的几种方法1.使用shellapi打开系统中默认的浏览器              首先需在头部引用 shellapi单元即在uses中添加shellapi,这里我们需要知道有 ...

  8. springboot Serving Web Content with Spring MVC

    Serving Web Content with Spring MVC This guide walks you through the process of creating a "hel ...

  9. iOS与Html5和JS之间的交互---学习笔记五

    首先采用的框架是WebViewJavascriptBridge,采用这套框架可以方便的使iOS与JS交互 一. 流程图(主要介绍思路) 二.iOS端如何使用 首先导入#import "Web ...

  10. jquery的css详解(一)

    通过阅读源码可以发现css是jq的实例方法.而在内部调用jq的工具方法access来实现的,对该方法不了解的朋友请点击 -> jquery工具方法access详解 在access的回调中做了一个 ...