标签:ati def inpu init 比较 color pid final asi
任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6319
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 5943 Accepted Submission(s): 2004
给出 N 个数的序列,求第 i 个长度为 M 的子串里的最大值与 i 的异或值 之和, 第 i 个长度为 M 的子串求的最大值的比较次数 与 i 的异或值之和;
为了简化输入样例,只给出前 K 个数,K~N个数可根据公式 ai=(p×ai?1+q×i+r)modMOD 求出;
用一个单调队列从后面往前面扫,队列的大小就是 需要比较交换的次数,队尾元素就是最大值。
AC code:
1 #include <deque> 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 #define INF 0x3f3f3f3f 7 #define LL long long 8 using namespace std; 9 10 const int MAXN = 1e7+10; 11 struct data 12 { 13 LL value; 14 int no; 15 }; 16 deque<struct data>que; 17 18 LL num[MAXN]; 19 LL N, M, K; 20 LL p, q, r, MOD; 21 22 int main() 23 { 24 int T_case; 25 scanf("%d", &T_case); 26 while(T_case--){ 27 que.clear(); 28 scanf("%lld %lld %lld %lld %lld %lld %lld", &N, &M, &K, &p, &q, &r, &MOD); 29 for(LL i = 1; i <= K; i++){ 30 scanf("%lld", &num[i]); 31 } 32 33 if(K < N){ 34 for(int i = K+1; i <= N; i++){ 35 num[i] = (p*num[i-1]+q*i+r)%MOD; 36 } 37 } 38 data it; 39 for(LL i = (N-M+1); i <= N; i++){ 40 if(que.empty() || que.back().value < num[i]){ 41 it.value = num[i]; 42 it.no = i; 43 que.push_back(it); 44 } 45 } 46 /* 47 while(!que.empty()){ 48 printf("%lld ", que.front()); 49 que.pop_front(); 50 } 51 */ 52 LL id = (N-M)+1; 53 //printf("id:%lld\n", id); 54 LL ans_A = (que.back().value^id); 55 LL ans_B = (que.size()^id); 56 for(LL i = (N-M); i >= 1; i--){ 57 if(que.back().no >= (i+M)) que.pop_back(); 58 while(que.front().value <= num[i] && !que.empty()) que.pop_front(); 59 it.value = num[i]; 60 it.no = i; 61 que.push_front(it); 62 id--; 63 ans_A += (que.back().value^id); 64 ans_B += (que.size()^id); 65 } 66 67 printf("%lld %lld\n", ans_A, ans_B); 68 } 69 70 return 0; 71 }
HDU 2018 Multi-University Training Contest 3 Problem A. Ascending Rating 【单调队列优化】
标签:ati def inpu init 比较 color pid final asi
原文地址:https://www.cnblogs.com/ymzjj/p/10291226.html