BSOJ4559:数颜色 带修改莫队算法
2016-02-18 14:22
246 查看
4559 -- 【模拟试题】数颜色
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≤20000,所有的输入数据中出现的所有整数均大于等于1且不超过10^6。
再记录一个修改序列,序列里记录pos,color,pre_color(修改前颜色)
cnt_change和cnt_query分别代表修改序列和查询序列的元素个数。
询问序列里再记录一个tim时间标记,每一次询问对应最近的一个修改,即tim(i)=cnt_change
按照(l->r->tim)的优先级排序
记录一个vis数组,表示元素i是否在当前工作序列中
其他的在注释里
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≤20000,所有的输入数据中出现的所有整数均大于等于1且不超过10^6。
再记录一个修改序列,序列里记录pos,color,pre_color(修改前颜色)
cnt_change和cnt_query分别代表修改序列和查询序列的元素个数。
询问序列里再记录一个tim时间标记,每一次询问对应最近的一个修改,即tim(i)=cnt_change
按照(l->r->tim)的优先级排序
记录一个vis数组,表示元素i是否在当前工作序列中
其他的在注释里
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; int ww=0,qq=0; struct alpha { int pos,col,pre; }w[200005]; struct query { int l,r,id,tim,ret; }q[200005]; int belong[200005]={0},block,last[200005]; bool vis[200005]={0}; int ans=0; int col[200005]={0}; int hash[2000005]={0}; int Ans[200005]; int n,m; bool cmp1(query a,query b) { if(belong[a.l]==belong[b.l]&&a.r==b.r)return a.tim<b.tim; if(belong[a.l]==belong[b.l])return a.r<b.r; return a.l<b.l; } void Getdata(int x) { if(vis[x]) { if(--hash[col[x]]==0)ans--; } else { if(++hash[col[x]]==1)ans++; } vis[x]^=1; } void Modify(int x,int c) { if(vis[x]) { Getdata(x); col[x]=c; Getdata(x); } else col[x]=c; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&col[i]),last[i]=col[i]; block=pow(n,2.0/3); for(int i=1;i<=n;i++)belong[i]=(i-1)/block+1; for(int i=1;i<=m;i++) { char cmd; int x,y; cin>>cmd; scanf("%d%d",&x,&y); if(cmd=='R') { w[++ww].pos=x;w[ww].col=y;w[ww].pre=last[x]; last[x]=y; } if(cmd=='Q') { q[++qq].l=x;q[qq].r=y;q[qq].id=qq;q[qq].tim=ww; } } sort(q+1,q+qq+1,cmp1); int l=1,r=0; for(int i=1;i<=qq;i++) { for(int j=q[i-1].tim+1;j<=q[i].tim;j++)Modify(w[j].pos,w[j].col);//每新来一个点,把它之前需要修改的进行修改 for(int j=q[i-1].tim;j>q[i].tim;j--)Modify(w[j].pos,w[j].pre);//时间回流,因为排序后的序列不是时间有序的,可能在询问时已经多做了时间轴之后的修改,要改回去。 for(;r<q[i].r;)Getdata(++r); for(;r>q[i].r;)Getdata(r--); for(;l<q[i].l;)Getdata(l++); for(;l>q[i].l;)Getdata(--l); Ans[q[i].id]=ans;//hash排序 } for(int i=1;i<=qq;i++)printf("%d\n",Ans[i]); return 0; }
相关文章推荐
- log4j使用
- 线程调用例子
- 线程调用例子
- JS对象属性使用的问题
- Android如何处理需要分屏分组的设置项
- HDU2050递归
- web.xml中contextConfigLocation的作用
- 关于group by 两个或以上条件的分析
- 6、函数
- maven-anturn-plugin插件使用
- Java线程(篇外篇):阻塞队列BlockingQueue
- Uploadify批量上传后台传参问题
- java.lang.ClassNotFoundException: org.apache.xmlbeans.XmlOptions
- Java面向对象的基本知识<二>
- leetcode之-题19
- 全国各大城市Uber客服联系方式(电话、邮箱、微博)
- Cocoapods安装和使用教程
- 19个MySQL性能优化要点解析
- Exception in thread "http-bio-8080-exec-2" java.lang.OutOfMemoryError: PermGen space[解决方案]
- VHDL快速参考手册