标签:
1008 Function
题解:如果a>=b,那么a%b<=a/2;
一个数n从本来的位置递减到0最多只需要logn次,也就是往右递减的位置最多不超过30个,那么我们就可以预处理出每个数往右递减的位置,然后离线询问,
用一个优先队列存储数和数所在的位置,比如8 7 6 9 10,先push(8,1)进去,然后每次把队首拿出来,8%7=1,把(1,1)push进去,然后把(8,1)pop出来,(7,2)push进去,优先队列最大值优先,当队首元素小于当前元素的时候,把当前元素和位置push进去,开始枚举下一个数
1 #include <iostream> 2 #include <algorithm> 3 #include <stdio.h> 4 #include <string.h> 5 #include <stdlib.h> 6 #include <queue> 7 using namespace std; 8 const int maxn=1e5+10; 9 struct node 10 { 11 int id; 12 int data; 13 int cnt; 14 friend bool operator < (const node&a,const node&b) 15 { 16 return a.data<b.data; 17 } 18 }; 19 struct node2 20 { 21 int pos; 22 int data; 23 void init() 24 { 25 pos=0; 26 } 27 }; 28 node a[maxn]; 29 node2 pos[maxn][32]; 30 priority_queue<node> q; 31 int main() 32 { 33 int T; 34 scanf("%d",&T); 35 while(T--) 36 { 37 while(!q.empty()) q.pop(); 38 int n; 39 scanf("%d",&n); 40 for(int i=1;i<=n;i++) 41 { 42 int x; 43 scanf("%d",&x); 44 a[i].data=x; 45 a[i].id=i; 46 a[i].cnt=0; 47 pos[i][0].data=x; 48 pos[i][0].pos=i; 49 for(int j=1;j<=30;j++) 50 { 51 pos[i][j].init(); 52 } 53 } 54 q.push(a[1]); 55 for(int i=2;i<=n;i++) 56 { 57 node tmp; 58 while(q.top().data>=a[i].data) 59 { 60 tmp=q.top(); 61 q.pop(); 62 tmp.data%=a[i].data; 63 tmp.cnt+=1; 64 pos[tmp.id][tmp.cnt].pos=i; 65 pos[tmp.id][tmp.cnt].data=tmp.data; 66 q.push(tmp); 67 68 } 69 q.push(a[i]); 70 } 71 int m; 72 scanf("%d",&m); 73 while(m--) 74 { 75 int l,r; 76 int ans; 77 scanf("%d %d",&l,&r); 78 if(l==r){ 79 printf("%d\n",a[l].data); 80 continue; 81 } 82 else 83 { 84 for(int i=0;i<=30;i++) 85 { 86 87 if(pos[l][i].pos>r||pos[l][i].pos==0) break; 88 ans=pos[l][i].data; 89 } 90 printf("%d\n",ans); 91 } 92 } 93 94 } 95 return 0; 96 }
标签:
原文地址:http://www.cnblogs.com/as3asddd/p/5861648.html