Light OJ 1188
来源:互联网 发布:人工智能ai 下载 编辑:程序博客网 时间:2024/06/05 09:35
详细:view
题目意思特别好懂,就是找任意区间有多少个不同的数。
开始用dp做,结果MTL,后来看了提示,才会用树状数组做。
其实个人觉得题目难点就在保存出现重复的点的位置,代码中使用vis[N]记录第i个点是否重复,不重复就记为0,若重复则记录与它重复的数的位置,使用vis的目的就是用来更新树状数组的,发现vis!=0时,说明有重复元素出现,所以应该把重复的元素的位置的值减1。还有一个就是离线操作。
大致主要的思路就是这样。
#include<iostream>#include<cstdio>#include<cstring>#include<vector>#define sf scanf#define pf printfusing namespace std;const int N=3+1e5;int vis[N],bk[N];int tree[N],a[N],ans[N],n;typedef struct node{ int idex,left;}node;vector<node> q[N];int read(int pos){ int as=0; while(pos>0) as+=tree[pos],pos-=pos&-pos; return as;}void update(int pos,int val){ while(pos<=n) tree[pos]+=val,pos+=pos&-pos;}void unit(){ memset(tree,0,sizeof(tree)); memset(bk,0,sizeof(bk)); for(int i=1;i<N;i++) q[i].clear();}int main(){ int t,ca=0; node tmp; sf("%d",&t); while(t--) { int qn; sf("%d%d",&n,&qn); unit(); for(int i=1;i<=n;i++) sf("%d",&a[i]); for(int i=1;i<=n;i++) vis[i]=bk[a[i]],bk[a[i]]=i; for(int i=1;i<=qn;i++) { int l,r; sf("%d%d",&l,&r); tmp.idex=i,tmp.left=l; q[r].push_back(tmp); } //for(int i=1;i<=n;i++) pf("%d ",vis[i]); for(int i=1;i<=n;i++) { if(vis[i]) update(vis[i],-1); update(i,1); for(int j=0;j<q[i].size();j++) { int tt=q[i][j].idex,l=q[i][j].left; ans[tt]=read(i)-read(l-1); } } pf("Case %d:\n",++ca); for(int i=1;i<=qn;i++) pf("%d\n",ans[i]); } return 0;}
0 0
- Light OJ 1188
- light oj
- light oj
- Light OJ
- Light OJ
- Light OJ 1000
- Light OJ 1001
- Light OJ 1008
- Light OJ 1022
- Light OJ 1015
- Light OJ 1042
- light oj 1128
- Light OJ 1055 BFS
- Light OJ Beginners Problems
- Light OJ Basic Geometry
- Light OJ Basic Math
- light oj 1124
- Light OJ 1012
- WPF体系结构简述
- linux驱动摸索 --printk的使用(结合韦东山视频教程)
- AVAudioPlayer播放音频
- 黑马程序员10.String&StringBuffer
- Apache2 配置禁止显示目录列表
- Light OJ 1188
- 2029 Palindromes _easy version(回文数简单版)
- POJ 1156 Palindrome (最长公共子序列)
- python
- lua 操作系统库
- NSString应用copy和strong的区别
- vi & vim 打开、关闭、保存文件
- iOS开发 获取当前WIFI的SSID
- 第二次签到