HDU4630-No Pain No Game(离线,线段树)
Problem Description
Life is a game,and you lose it,so you suicide.
But you can not kill yourself before you solve this problem:
Given you a sequence of number a1, a2, ..., an.They are also a permutation of 1...n.
You need to answer some queries,each with the following format:
If we chose two number a,b (shouldn't be the same) from interval [l, r],what is the maximum gcd(a, b)? If there's no way to choose two distinct number(l=r) then the answer is zero.
But you can not kill yourself before you solve this problem:
Given you a sequence of number a1, a2, ..., an.They are also a permutation of 1...n.
You need to answer some queries,each with the following format:
If we chose two number a,b (shouldn't be the same) from interval [l, r],what is the maximum gcd(a, b)? If there's no way to choose two distinct number(l=r) then the answer is zero.
Input
First line contains a number T(T <= 5),denote the number of test cases.
Then follow T test cases.
For each test cases,the first line contains a number n(1 <= n <= 50000).
The second line contains n number a1, a2, ..., an.
The third line contains a number Q(1 <= Q <= 50000) denoting the number of queries.
Then Q lines follows,each lines contains two integer l, r(1 <= l <= r <= n),denote a query.
Then follow T test cases.
For each test cases,the first line contains a number n(1 <= n <= 50000).
The second line contains n number a1, a2, ..., an.
The third line contains a number Q(1 <= Q <= 50000) denoting the number of queries.
Then Q lines follows,each lines contains two integer l, r(1 <= l <= r <= n),denote a query.
Output
For each test cases,for each query print the answer in one line.
Sample Input
1
10
8 2 4 9 5 7 10 6 1 3
5
2 10
2 4
6 9
1 4
7 10
Sample Output
5 2 2 4 3
题目大意:
给一个序列,然后q次询问[l,r]询问两两gcd最大值是多少(不能是同一个数),无解输出0;
解题思路:
想总结一下,感觉自己好菜啊。
两两取gcd,最后的值肯定是该数的约数。
也就是说,数是可以一个一个加入的。
现将约数分解。
一个数被加入。如果他的约数k上一次在p处,那么询问左端点<=p的话答案就至少值为k。
就离线处理一下。
保证加入的点来更新答案。
我觉得和HH的项链有点像。
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define lll spc<<1 5 #define rrr spc<<1|1 6 using std::max; 7 struct qst{ 8 int l,r; 9 int no; 10 int ans; 11 void Insert(int i) 12 { 13 no=i; 14 ans=0; 15 scanf("%d%d",&l,&r); 16 return ; 17 } 18 }q[1000000]; 19 int maxs[1000000]; 20 int a[1000005]; 21 int lst[1000005]; 22 int n,Q; 23 int T; 24 bool cmp(qst x,qst y) 25 { 26 return x.r<y.r; 27 } 28 bool cmq(qst x,qst y) 29 { 30 return x.no<y.no; 31 } 32 void Reset(void) 33 { 34 memset(lst,0,sizeof(lst)); 35 memset(maxs,0,sizeof(maxs)); 36 return ; 37 } 38 void pushup(int spc) 39 { 40 maxs[spc]=max(maxs[lll],maxs[rrr]); 41 return ; 42 } 43 void update(int spc,int l,int r,int v,int pos) 44 { 45 if(l==r) 46 { 47 maxs[spc]=max(v,maxs[spc]); 48 return ; 49 } 50 int mid=(l+r)>>1; 51 if(pos<=mid) 52 update(lll,l,mid,v,pos); 53 else 54 update(rrr,mid+1,r,v,pos); 55 pushup(spc); 56 return ; 57 } 58 int query(int l,int r,int ll,int rr,int spc) 59 { 60 if(l>rr||ll>r) 61 return -0x3f3f3f3f; 62 if(ll<=l&&r<=rr) 63 return maxs[spc]; 64 int mid=(l+r)>>1; 65 return max(query(l,mid,ll,rr,lll),query(mid+1,r,ll,rr,rrr)); 66 } 67 int main() 68 { 69 scanf("%d",&T); 70 while(T--) 71 { 72 Reset(); 73 scanf("%d",&n); 74 for(int i=1;i<=n;i++) 75 scanf("%d",&a[i]); 76 scanf("%d",&Q); 77 for(int i=1;i<=Q;i++) 78 q[i].Insert(i); 79 std::sort(q+1,q+Q+1,cmp); 80 int j=1; 81 for(int i=1;i<=n;i++) 82 { 83 for(int k=1;k*k<=a[i];k++) 84 { 85 if(a[i]%k==0&&lst[k]) 86 update(1,1,n,k,lst[k]); 87 if(a[i]%k==0&&lst[a[i]/k]&&k!=a[i]/k) 88 update(1,1,n,a[i]/k,lst[a[i]/k]); 89 if(a[i]%k==0) 90 lst[k]=lst[a[i]/k]=i; 91 } 92 while(q[j].r==i) 93 { 94 if(j>Q) 95 break; 96 if(q[j].l>=q[j].r) 97 q[j].ans=0; 98 else 99 q[j].ans=query(1,n,q[j].l,q[j].r,1); 100 j++; 101 } 102 } 103 std::sort(q+1,q+Q+1,cmq); 104 for(int i=1;i<=Q;i++) 105 printf("%d\n",q[i].ans); 106 } 107 return 0; 108 }