【HDOJ】3601 Coach Yehr’s punishment

RMQ+dp+二分。
最好还是离散化一下再处理,通过dp求得每个位置的上一次出现的位置pre数组,从而求得不重复的长度len。
然后RMQ可以预处理区间的最大值,pre是个单调非递减数列。每次查询时,二分可以找到超过l的位置。
注意这个位置k可能超过r。因此最大值为max(k-l, RMQ(k, r) && k<=r)。

  1 /* 3603 */
  2 #include <iostream>
  3 #include <sstream>
  4 #include <string>
  5 #include <map>
  6 #include <queue>
  7 #include <set>
  8 #include <stack>
  9 #include <vector>
 10 #include <deque>
 11 #include <algorithm>
 12 #include <cstdio>
 13 #include <cmath>
 14 #include <ctime>
 15 #include <cstring>
 16 #include <climits>
 17 #include <cctype>
 18 #include <cassert>
 19 #include <functional>
 20 #include <iterator>
 21 #include <iomanip>
 22 using namespace std;
 23 //#pragma comment(linker,"/STACK:102400000,1024000")
 24 
 25 #define sti                set<int>
 26 #define stpii            set<pair<int, int> >
 27 #define mpii            map<int,int>
 28 #define vi                vector<int>
 29 #define pii                pair<int,int>
 30 #define vpii            vector<pair<int,int> >
 31 #define rep(i, a, n)     for (int i=a;i<n;++i)
 32 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 33 #define clr                clear
 34 #define pb                 push_back
 35 #define mp                 make_pair
 36 #define fir                first
 37 #define sec                second
 38 #define all(x)             (x).begin(),(x).end()
 39 #define SZ(x)             ((int)(x).size())
 40 #define lson            l, mid, rt<<1
 41 #define rson            mid+1, r, rt<<1|1
 42 
 43 const int maxn = 1e6+5;
 44 int pre[maxn], len[maxn], pos[maxn];
 45 int dp[20][maxn];
 46 int a[maxn];
 47 int n;
 48 
 49 void init_RMQ(int n) {
 50     int i, j;
 51     
 52     for (i=1; i<=n; ++i)
 53         dp[0][i] = len[i];
 54     for (j=1; (1<<j)<=n; ++j)
 55         for (i=1; i+(1<<j)-1<=n; ++i)
 56             dp[j][i] = max(dp[j-1][i], dp[j-1][i+(1<<(j-1))]);
 57 }
 58 
 59 int RMQ(int l, int r) {
 60     if (l > r)
 61         swap(l, r);
 62     
 63     int k = 0;
 64     
 65     while (1<<(k+1) <= r-l+1)
 66         ++k;
 67     
 68     return max(dp[k][l], dp[k][r-(1<<k)+1]);
 69 }
 70 
 71 void solve() {
 72     memset(pos, 0, sizeof(pos));
 73     rep(i, 1, n+1) {
 74         if (pos[a[i]] == 0)
 75             pre[i] = 0;
 76         else
 77             pre[i] = pos[a[i]];
 78         pre[i] = max(pre[i], pre[i-1]);
 79         pos[a[i]] = i;
 80         len[i] = i - pre[i];
 81     }
 82     
 83     init_RMQ(n);
 84     
 85     int q;
 86     int l, r;
 87     int ans;
 88     
 89     scanf("%d", &q);
 90     while (q--) {
 91         scanf("%d %d", &l, &r);
 92         if (l > r)
 93             swap(l, r);
 94         int k = lower_bound(pre+l, pre+r+1, l) - pre;
 95         ans = k - l;
 96         if (k <= r)
 97             ans = max(ans, RMQ(k, r));
 98         printf("%d
", ans);
 99     }
100 }
101 
102 int main() {
103     ios::sync_with_stdio(false);
104     #ifndef ONLINE_JUDGE
105         freopen("data.in", "r", stdin);
106         freopen("data.out", "w", stdout);
107     #endif
108     
109     while (scanf("%d", &n)!=EOF) {
110         rep(i, 1, n+1)
111             scanf("%d", &a[i]);
112         solve();
113     }
114     
115     #ifndef ONLINE_JUDGE
116         printf("time = %d.
", (int)clock());
117     #endif
118     
119     return 0;
120 }

数据生成器。

 1 from random import randint, shuffle
 2 import shutil
 3 import string
 4 
 5 
 6 def GenDataIn():
 7     with open("data.in", "w") as fout:
 8         t = 1
 9         bound = 10**3
10         for tt in xrange(t):
11             n = randint(100, 200)
12             fout.write("%d
" % (n))
13             dataList = []
14             for i in xrange(n):
15                 x = randint(1, 100)
16                 dataList.append(x)
17             fout.write(" ".join(map(str, dataList)) + "
")
18             q = randint(100, 200)
19             fout.write("%d
" % (q))
20             for i in xrange(q):
21                 l = randint(1, n)
22                 r = randint(l, n)
23                 fout.write("%d %d
" % (l, r))
24                 
25 def MovDataIn():
26     desFileName = "F:eclipse_prjworkspacehdojdata.in"
27     shutil.copyfile("data.in", desFileName)
28 
29     
30 if __name__ == "__main__":
31     GenDataIn()
32     MovDataIn()
原文地址:https://www.cnblogs.com/bombe1013/p/5184417.html