Gym
来源:互联网 发布:mac如何卸载app 编辑:程序博客网 时间:2024/06/08 11:41
题目地址:http://codeforces.com/gym/101201/attachments
思路:
1.题目相当于对于一数,依次对[L,R]区间内的数取模,结果即为答案。
2.若对于区间内一大于v的数,其取模结果仍为本身,无作用。则问题变为快速寻找区间内第一个不大于v的数(区间内数无序)。
3.考虑二分区间[L,R],mid=(L+R)/2。若区间[L,mid]内最小值不大于v则说明第一个不大于v的数在该区间内,否则第一个不大于v的数在[mid+1,R]内,不断二分即可找到该数。
4.每次找到该数的位置后,下次区间查找范围为[pos,R],直到该区间内不存在小于v的数或v已经为0。
4.每次取模v%x<=v/2,则复杂度为log级别,查找同样为log级,时间可接受。
#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define debugusing namespace std;typedef long long LL;const int maxn=200000+50;int n,q;LL a[maxn];int preLog2[maxn];LL stTable[maxn][20];void st_prepare(int n,LL* arr){ preLog2[1]=0; for(int i=2; i<=n; i++) { preLog2[i]=preLog2[i-1]; if((1<<preLog2[i]+1)==i) { ++preLog2[i]; } } for(int i=n-1; i>=0; i--) { stTable[i][0]=arr[i]; for(int j=1; (i+(1<<j)-1)<n; j++) { stTable[i][j]=min(stTable[i][j-1],stTable[i+(1<<j-1)][j-1]); } }}LL query_min(int l,int r){ int len=r-l+1,k=preLog2[len]; return min(stTable[l][k],stTable[r-(1<<k)+1][k]);}int getPos(int l,int r,LL v){ int L=l,R=r,ans=n+1; while(L<=R) { int mid=(L+R)/2; if(query_min(L,mid)<=v) { ans=mid; R=mid-1; } else { L=mid+1; } } return ans;}int main(){#ifdef debu freopen("in.txt","r",stdin);#endif // debug scanf("%d%d",&n,&q); for(int i=0; i<n; i++) scanf("%lld",&a[i]); st_prepare(n,a); for(int i=0; i<q; i++) { LL v; int l,r,pos; scanf("%lld%d%d",&v,&l,&r); l--,r--; while(l<=r) { v%=a[l]; if(!v) break; l=getPos(l,r,v); } printf("%lld\n",v); } return 0;}
阅读全文
0 0
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- java se基础知识
- http请求和响应详解
- Android自学笔记之UI组件:TextView组件
- ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 A题 Visiting Peking University
- Kth Largest Element in an Array
- Gym
- css3 media媒体查询器用法总结
- 设计模式-单例模式
- centos下安装python3
- 算法与数据结构-堆的基本操作C语言实现
- 有关linux串口通信
- 支持向量机svm由浅到深
- javaScript屏蔽鼠标右键,F12及其它审查元素功能
- kmp