【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\n", 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.\n", (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" % (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)) + "\n") 18 q = randint(100, 200) 19 fout.write("%d\n" % (q)) 20 for i in xrange(q): 21 l = randint(1, n) 22 r = randint(l, n) 23 fout.write("%d %d\n" % (l, r)) 24 25 def MovDataIn(): 26 desFileName = "F:\eclipse_prj\workspace\hdoj\data.in" 27 shutil.copyfile("data.in", desFileName) 28 29 30 if __name__ == "__main__": 31 GenDataIn() 32 MovDataIn()