[BZOJ2120] 数颜色
2015-07-14 09:42
288 查看
2120: 数颜色
Time Limit: 6 Sec Memory Limit: 259 MBSubmit: 1884 Solved: 749
[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 51 2 3 4 5 5
Q 1 4
Q 2 6
R 1 2
Q 1 4
Q 2 6
Sample Output
44
3
4
HINT
对于100%的数据,N≤10000,M≤10000,修改操作不多于1000次,所有的输入数据中出现的所有整数均大于等于1且不超过10^6。Source
本来想从HZWER找个分块的题做,结果发现这题根本不用分块……直接暴力就好了。首先离散化一下,颜色从1开始标号,映射到map数组里。询问时,每次用f数组记录时间戳(bool清零浪费时间),然后判重就好了。
2S过……
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<vector> using namespace std; int n,m,x,y,t,ans,tot,map[1000001],a[12001],f[12001]; char c[5]; int main() { scanf("%d%d",&n,&m); tot=0; t=0; for (int i=1;i<=n;i++) { scanf("%d",&x); if (map[x]==0) map[x]=++tot; a[i]=map[x]; } for (int i=1;i<=m;i++) { scanf("%s%d%d",c,&x,&y); if (c[0]=='Q') { ans=0; ++t; for (int j=x;j<=y;j++) if (f[a[j]]!=t) { ans++; f[a[j]]=t; } printf("%d\n",ans); } if (c[0]=='R') { if (map[y]==0) map[y]=++tot; a[x]=map[y]; } } return 0; }
分块:
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<vector> #include<map> using namespace std; int n,m,x,y,block,qq,c[10001],pos[10001],pre[10001],b[10001],last[1000001]; char ch[5]; void reset(int x) { int l=(x-1)*block+1,r=min(n,x*block); for (int i=l;i<=r;i++) pre[i]=b[i]; sort(pre+l,pre+r+1); } void build() { for (int i=1;i<=n;i++) { b[i]=last[c[i]]; last[c[i]]=i; pos[i]=(i-1)/block+1; } for (int i=1;i<=m;i++) reset(i); } void change(int x,int y) { for (int i=1;i<=n;i++) last[c[i]]=0; c[x]=y; for (int i=1;i<=n;i++) { int t=b[i]; b[i]=last[c[i]]; if (t!=b[i]) reset(pos[i]); last[c[i]]=i; } } int find(int x,int v) { int l=(x-1)*block+1,r=min(x*block,n); int first=l; while (l<=r) { int mid=(l+r)>>1; if (pre[mid]<v) l=mid+1; else r=mid-1; } return l-first; } int ask(int x,int y) { int ans=0; if (pos[x]==pos[y]) { for (int i=x;i<=y;i++) if (b[i]<x) ans++; } else { for (int i=x;i<=pos[x]*block;i++) if (b[i]<x) ans++; for (int i=(pos[y]-1)*block+1;i<=y;i++) if (b[i]<x) ans++; } for (int i=pos[x]+1;i<pos[y];i++) ans+=find(i,x); return ans; } int main() { scanf("%d%d",&n,&qq); for (int i=1;i<=n;i++) scanf("%d",&c[i]); block=int(sqrt(n)); if (n%block) m=n/block+1; else m=n/block; build(); for (int i=1;i<=qq;i++) { scanf("%s%d%d",ch,&x,&y); if (ch[0]=='Q') printf("%d\n",ask(x,y)); if (ch[0]=='R') change(x,y); } return 0; }
相关文章推荐
- 项目实战之中小网站数据缓存的设计与实现
- sizeof,终极无惑『转』
- delegate anonymous method and lambda express
- 自定义相机预览界面
- 正则表达式集合
- HDU 2124 Repair the Wall
- 时间都去哪了
- 63 change事件监控raido选中效果
- Touch事件分发机制
- block----
- 滚动view的嵌套。
- UITableView 以及 UITableViewCell 的重用机制
- Bitmap与BitmapFactory.Options
- cpu亲和力总结taskset和setcpu及其他相关
- Java设计模式(三)原型模型 适配器型号
- 自定义类似RadioButton的单选、多选的ListView
- 国内云计算平台个人点评
- dell Poweredg 系列服务器整列卡及网、显卡驱动所以列表
- 缓存技术PK:选择Memcached还是Redis?
- 【转】计算机视觉基础2——相机成像的几何描述