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\n",ans[i]);

94     }

95     return 0;

96 }
View Code

 

你可能感兴趣的:(game)