您的位置:首页 > 大数据 > 人工智能

Pair of Numbers

2017-03-01 15:40 288 查看
题意:

给一长度为n的正整数序列,对于一个$[l,r]$,如果存在$d ∈ [l,r]$ 满足 $a(d)|a(i) (i∈[l, r])$ 则称之为合法子串。

找出所有的最长合法子串。

解法:

1. $O(n \sum_{i=1}^n {\tau ( a(i) ) })$ 做法,枚举a序列中出现的数字d,将 i*d 所在的位置标上1,

然后从所有d所在的位置左右暴力拓展。

注意到只有下一位为1时才会拓展,所以暴力拓展的复杂度和标1的复杂度相同。

考虑每个数字a(i),最多被访问了它的约数次,所以总复杂度 $O(n \sum_{i=1}^n {\tau ( a(i) ) })$

1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <vector>
5 #include <algorithm>
6
7 #define N 300010
8 #define M 1000010
9
10 using namespace std;
11
12 int n,m,tot,ans,a
,a0
;
13 bool del
;
14 vector<int> pos[M],ansv;
15
16 int main()
17 {
18 //    freopen("test.txt","r",stdin);
19     while(~scanf("%d",&n))
20     {
21         for(int i=1;i<=n;i++) del[i]=0;
22         ansv.clear();
23         ans=m=1;
24         for(int i=1;i<=n;i++)
25         {
26             scanf("%d",&a[i]);
27             m = max(m, a[i]);
28             pos[a[i]].push_back(i);
29             a0[i]=a[i];
30         }
31         sort(a0+1,a0+n+1);
32         tot=1;
33         for(int i=2;i<=n;i++)
34             if(a0[i]!=a0[i-1]) a0[++tot]=a0[i];
35         for(int d=1;d<=tot;d++)
36         {
37             int x=a0[d];
38             int len=pos[x].size();
39             for(int i=0;i<len;i++)
40             {
41                 int tmp=pos[x][i];
42                 if(del[tmp]) continue;
43                 del[tmp]=1;
44                 int l=tmp,r=tmp;
45                 while(l>1 && a[l-1]%x==0) del[--l]=1;
46                 while(r<n && a[r+1]%x==0) del[++r]=1;
47                 if(r-l+1>ans)
48                 {
49                     ans=r-l+1;
50                     ansv.clear();
51                     ansv.push_back(l);
52                 }
53                 else if(r-l+1==ans)
54                     ansv.push_back(l);
55             }
56         }
57         for(int i=1;i<=m;i++) pos[i].clear();
58         int len=ansv.size();
59         cout << len << ' ' << ans-1 << endl;
60         sort(ansv.begin(), ansv.end());
61         for(int i=0;i<len;i++) cout << ansv[i] << ' ';
62         cout << endl;
63     }
64     return 0;
65 }


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: