【BZOJ 2120】 数颜色 (乱搞分块,直指暴力)
2016-03-16 21:19
295 查看
题目链接:
http://www.lydsy.com/JudgeOnline/problem.php?id=2120
题解:
超级无敌大暴力,简直醉了,算法复杂度(m*(根号m+1000)),假如没有修改,那么这就是个明显的莫队,然而其中有修改就比较坑了,但是我们注意到修改次数最多只有1000,啥都不说,先莫队,每次到查询 i 的区间时暴力的搜所有的修改操作来修改本次的答案,之后再改回去,不过注意有时候会多次修改同一个位置。。。。。
据说也可以不用分块,只需要离散化后暴力就行,而且只要两秒。。。
代码:
http://www.lydsy.com/JudgeOnline/problem.php?id=2120
题解:
超级无敌大暴力,简直醉了,算法复杂度(m*(根号m+1000)),假如没有修改,那么这就是个明显的莫队,然而其中有修改就比较坑了,但是我们注意到修改次数最多只有1000,啥都不说,先莫队,每次到查询 i 的区间时暴力的搜所有的修改操作来修改本次的答案,之后再改回去,不过注意有时候会多次修改同一个位置。。。。。
据说也可以不用分块,只需要离散化后暴力就行,而且只要两秒。。。
代码:
#include<iostream> #include<algorithm> #include<stdio.h> #include<math.h> #include<string.h> #define maxn (100005) using namespace std; struct node{ int l;int r; int id;int t; }q[maxn],c[maxn]; int n,m,len,a[maxn],sq[maxn],cnt[1000005],ans[maxn],gai[maxn]; char p[2]; int cmp(node x,node y) { int idx=(x.l)/len; int idy=(y.l)/len; if (idx!=idy) return idx<idy; return x.r<y.r; } int main() { memset(gai,-1,sizeof(gai)); scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d",&a[i]); len=sqrt(n); int numq=0,numc=0; for (int i=1;i<=m;i++) { int x,y; scanf("%s%d%d",p,&x,&y); if (p[0]=='Q') { numq++; q[numq].l=x;q[numq].r=y; q[numq].id=numq; q[numq].t=i; } else { numc++; c[numc].l=x;c[numc].r=y; c[numc].t=i; } } sort(q+1,q+1+numq,cmp); int nol=0,nor=0; int noa=0; for (int i=1;i<=numq;i++) { while(q[i].r < nor) { cnt[a[nor]]--; if (cnt[a[nor]]==0) noa--; nor--; } while(q[i].r > nor) { nor++; cnt[a[nor]]++; if (cnt[a[nor]]==1) noa++; } while(q[i].l < nol) { nol--; cnt[a[nol]]++; if (cnt[a[nol]]==1) noa++; } while(q[i].l > nol) { cnt[a[nol]]--; if (cnt[a[nol]]==0) noa--; nol++; } for (int j=1;j<=numc;j++) { int x=c[j].l; int y=c[j].r; int tmp=c[j].t; if (x>=q[i].l && x<=q[i].r && tmp<q[i].t) { if (gai[x]!=-1) { cnt[gai[x]]--; if (cnt[gai[x]]==0) noa--; } else { cnt[a[x]]--; if (cnt[a[x]]==0) noa--; } gai[x]=y; cnt[y]++; if (cnt[y]==1) noa++; } } ans[q[i].id]=noa; // cout<<q[i].id<<' '<<noa<<endl; for (int j=1;j<=numc;j++) { int x=c[j].l; int y=c[j].r; int tmp=c[j].t; if (x>=q[i].l && x<=q[i].r && tmp<q[i].t) { if (gai[x]==y) { cnt[gai[x]]--; if (cnt[gai[x]]==0) noa--; cnt[a[x]]++; if (cnt[a[x]]==1) noa++; gai[x]=-1; } } } // cout<<noa<<endl; } for (int i=1;i<=numq;i++) printf("%d\n",ans[i]); }
相关文章推荐
- forward和redirect的区别
- Symantec System Recovery 笔记
- 附加到iis进程调试时找不到w3wp.exe
- C++用模板实现双链表和队列
- linux中awk命令详解
- PagerAdapter学习
- Salt自动化之自动更新Gitfs-爱折腾技术网
- 《linux内核设计与实现》读书笔记第一、二章
- [code]判断周期串
- 林大OJ 60
- Oracle sql, 外键,级联
- Android自定义View之六位密码框
- LinearLayout的一些注意事项和ayout_gravity与gravity的区别
- NIO
- 转载:纹理分类(一)全局特征
- 关于变量值的互换和求一组数的最大数,程序的那些事
- 计算完全最短路径的Floyd算法
- 【问题集】Provided dependencies can only be jars
- Android基础-Intent用法
- C