【HDOJ】5288 OO’s Sequence
二分寻找对于指定pos的最左因数点和最右因数点。
1 /* 5288 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <deque> 10 #include <algorithm> 11 #include <cstdio> 12 #include <cmath> 13 #include <ctime> 14 #include <cstring> 15 #include <climits> 16 #include <cctype> 17 #include <cassert> 18 #include <functional> 19 #include <iterator> 20 #include <iomanip> 21 using namespace std; 22 //#pragma comment(linker,"/STACK:102400000,1024000") 23 24 #define sti set<int> 25 #define stpii set<pair<int, int> > 26 #define mpii map<int,int> 27 #define vi vector<int> 28 #define pii pair<int,int> 29 #define vpii vector<pair<int,int> > 30 #define rep(i, a, n) for (int i=a;i<n;++i) 31 #define per(i, a, n) for (int i=n-1;i>=a;--i) 32 #define clr clear 33 #define pb push_back 34 #define mp make_pair 35 #define fir first 36 #define sec second 37 #define all(x) (x).begin(),(x).end() 38 #define SZ(x) ((int)(x).size()) 39 #define lson l, mid, rt<<1 40 #define rson mid+1, r, rt<<1|1 41 42 const int mod = 1e9+7; 43 const int maxn = 1e5+5; 44 const int maxm = 10005; 45 vi vc[maxm]; 46 vi fac[maxm]; 47 int a[maxn]; 48 49 void init() { 50 int i, j, k; 51 52 for (i=1; i<maxm; ++i) { 53 for (j=1; j*j<=i; ++j) { 54 if (i%j == 0) { 55 fac[i].pb(j); 56 k = i / j; 57 if (k != j) 58 fac[i].pb(k); 59 } 60 } 61 } 62 } 63 64 int main() { 65 ios::sync_with_stdio(false); 66 #ifndef ONLINE_JUDGE 67 freopen("data.in", "r", stdin); 68 freopen("data.out", "w", stdout); 69 #endif 70 71 int n; 72 int l, r, tmp; 73 vi::iterator iter; 74 __int64 ans; 75 76 init(); 77 while (scanf("%d", &n) != EOF) { 78 rep(i, 1, n+1) { 79 scanf("%d", &a[i]); 80 vc[a[i]].pb(i); 81 } 82 83 int sz; 84 ans = 0; 85 86 rep(i, 1, n+1) { 87 l = 0; 88 r = n+1; 89 sz = SZ(fac[a[i]]); 90 rep(j, 0, sz) { 91 tmp = fac[a[i]][j]; 92 iter = upper_bound(all(vc[tmp]), i); 93 if (iter != vc[tmp].end()) { 94 r = min(r, *iter); 95 } 96 if (iter!=vc[tmp].begin()) { 97 --iter; 98 if (*iter != i) 99 l = max(l, *iter); 100 else if (iter != vc[tmp].begin()) { 101 --iter; 102 l = max(l, *iter); 103 } 104 } 105 } 106 #ifndef ONLINE_JUDGE 107 tmp = (r-i) * (i-l); 108 // printf("%d: l = %d, r = %d, c = %d\n", i, l, r, tmp); 109 #endif 110 ans = (ans + 1LL * (r-i) * (i-l) % mod) % mod; 111 } 112 113 printf("%I64d\n", ans); 114 115 rep(i, 0, maxm) 116 vc[i].clear(); 117 } 118 119 #ifndef ONLINE_JUDGE 120 printf("time = %d.\n", (int)clock()); 121 #endif 122 123 return 0; 124 }