XCSY暑期集训模拟赛2T3善良
暴力(50pts)
对于每个询问,遍历\([l,r]\),统计其中k的数量,时间复杂度为\(O(nm)\)。
for(int i=1;i<=n;i++) cin>>a[i];
while(m--){cin>>l>>r>>k;int ans=0;for(int i=l;i<=r;i++){if(a[i]==k) ans++;}cout<<ans<<'\n';
}
二分(100pts)
用\(map[i]\)统计数字\(i\)出现的所有位置,每个\(map[i](1 \leq i \leq n)\)都是单调递增的。
对于每个询问,在\(map[k]\)中二分找到第一个\(\geq l\)和最后一个\(\leq r\)的数的位置,计算其中共包含多少个数即可(包含左右端点,具体见代码)
map<int,vector<int> >mp;//mp[i]表示数字i出现的所有位置
for(int i=1;i<=n;i++){cin>>a;mp[a].push_back(i);
}
while(m--){cin>>l>>r>>k;vector<int>v=mp[k];if(v.empty()||v[0]>r||v[v.size()-1]<l){//没有符合要求的数cout<<0<<'\n';continue;}int left=0,right=v.size()-1;while(left<right){int mid=left+right>>1;if(v[mid]<l) left=mid+1;else right=mid;}int x=right;//找第一个≥l的数的位置if(v[v.size()-1]<=r){//所有x以后的数均≤r,最后一个≤r的数的位置就是最后一个位置cout<<v.size()-x<<'\n';//左端点为x,右端点为v.size()-1,共有v.size()-1-x+1=v.size()-x个数}else{left=right,right=v.size()-1;while(left<right){int mid=left+right>>1;if(v[mid]>r) right=mid;else left=mid+1;}//找第一个>r的数的位置,减1就是最后一个≤r的数的位置cout<<left-x<<'\n';//左端点为x,右端点为left-1,共有left-1-x+1=left-x个数}
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/926261.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!