hdu4630No Pain No Game (多校3)(树状数组)

http://acm.hdu.edu.cn/showproblem.php?pid=4630

给的题解没看懂。。搜解题报告看 了N久  终于在cui大神的指点下 搞明白咋回事了

将1-N中的每个数ai的倍数的位置p求出来 它们任意两个p组成的区间内约数至少为ai 在询问的区间L-R中如果存在这样的区间pi-pj 那肯定存在相邻的 然后排好序 相邻的为一个区间l-r保存起来

以r从小到大排序 将输入的询问区间进行离线处理 以R由小到大排序 对于每个区间插入r值比R小的区间 求值时以L为下界求到N  其实就是求到R 到R还快了500多ms。 

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 using namespace std;
 7 #define N 50005
 8 #define lowbit(x) (x&(-x))
 9 int a[N],p[N],o[N],ans[N],re[N<<2],n;
10 struct node
11 {
12     int ll,r,val;
13 }tt[N*20],q[N];
14 bool cmp(node a,node b)
15 {
16     if(a.r==b.r)
17     return a.ll<b.ll;
18     return a.r<b.r;
19 }
20 void add(int x,int va)
21 {
22     while(x>0)
23     {
24         re[x]=max(re[x],va);
25         x-=lowbit(x);
26     }
27 }
28 int getsum(int x,int y)
29 {
30     int mm=0;
31     while(x<=y)
32     {
33         mm = max(mm,re[x]);
34         x += lowbit(x);
35     }
36     return mm;
37 }
38 int main()
39 {
40     int i,j,t,m;
41     cin>>t;
42     while(t--)
43     {
44         memset(re,0,sizeof(re));
45         cin>>n;
46         for(i = 1; i <= n ; i++)
47         {
48             scanf("%d",&a[i]);
49             p[a[i]] = i;
50             re[i] = 1;
51         }
52         int g,k=0;
53         for(i = 2 ; i <= n/2 ;i++)
54         {
55             g = 0;
56             for(j = i ; j <= n ; j+=i)
57             {
58                 o[g++] = p[j];
59             }
60             sort(o,o+g);
61             for(j = 1 ; j < g ; j++)
62             {
63                 tt[k].ll = o[j-1];
64                 tt[k].r = o[j];
65                 tt[k++].val = i;
66             }
67         }
68         sort(tt,tt+k,cmp);
69         cin>>m;
70         for(i = 1; i <= m ;i++)
71         {
72             scanf("%d%d",&q[i].ll,&q[i].r);
73             q[i].val = i;
74         }
75         sort(q+1,q+m+1,cmp);
76         int oo=0;
77 
78         for(i = 1; i <= m ;i++)
79         {
80             if(q[i].ll==q[i].r)
81             {
82                 ans[q[i].val] = 0;
83                 continue;
84             }
85             for(j = oo ; j < k&&tt[j].r<=q[i].r ; j++)
86              {
87                  add(tt[j].ll,tt[j].val);
88              }
89             ans[q[i].val] = getsum(q[i].ll,q[i].r);
90             oo = j;
91         }
92         for(i = 1 ;i <= m ;i++)
93         printf("%d
",ans[i]);
94     }
95     return 0;
96 }
View Code
原文地址:https://www.cnblogs.com/shangyu/p/3228469.html