Pair of Numbers

Codeforces Round #209 (Div. 2) D:http://codeforces.com/contest/359/problem/D

题意:给以一个n个数的序列,然后问你最大的区间l,r,在这个区间里面,存在一个数是这个区间所有数的约数,如果这个区间有多个,统计有多少个以及每个区间的左端点。

题解:这一题,别人用了一个很特殊的找发,让我叹为观止。哎,没有数学功底以及很强的推理能力,真的有点力不从心啊。说说别人是怎么找的吧。首先,从第一个数开始,往右边找,然后找到第一个不是a[1]倍数的数,这是第一个区间,然后从这个数让左边找,找到以这个数为约数的左边全歼,然后往右边找,找到不是这个数的倍数的那个数,并把这个数放进队列,因为这个数就是下一次要开始找的数,对于当前这个数,就会得到一个区间,然后进行相关的更新。接着又从队列中数,然后重复上面的 数,直到最后一个数。这里,别人的证明就是每个数最多被找logn次,自己画画图,好像是这样。所以复杂度就是nlogn.

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 using namespace std;
 7 const int N=3e5+10;
 8 int a[N],n;
 9 int ans[N],top;
10 int anss;
11 int main(){
12    while(~scanf("%d",&n)){
13     memset(ans,0,sizeof(ans));
14    memset(a,0,sizeof(a));
15    for(int i=1;i<=n;i++)
16      scanf("%d",&a[i]);
17      queue<int>Q;
18      anss=0;top=0;
19       Q.push(1);
20       while(!Q.empty()){
21         int x=Q.front();
22         Q.pop();
23        int num=1,ps=0;
24        for(int i=x-1;i>=1;i--){
25            if(a[i]%a[x]==0){
26             num++;
27            }
28            else
29               break;
30         }
31         ps=x-num+1;
32        for(int i=x+1;i<=n;i++){
33            if(a[i]%a[x]==0)
34             num++;
35            else{
36              Q.push(i);
37              break;
38            }
39          }
40         if(num>anss){
41             anss=num;top=0;
42             ans[++top]=ps;
43           }
44         else if(num==anss)
45            ans[++top]=ps;
46      }
47      printf("%d %d\n",top,anss-1);
48      for(int i=1;i<=top;i++){
49         if(i==top)printf("%d\n",ans[i]);
50         else
51             printf("%d ",ans[i]);
52      }
53    }
54 }
View Code

 

posted on 2014-08-06 19:57  天依蓝  阅读(296)  评论(0编辑  收藏  举报

导航