HDU5216--蜀道难(单调队列)
Posted __HPY_7m
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU5216--蜀道难(单调队列)相关的知识,希望对你有一定的参考价值。
题意:http://acm.hdu.edu.cn/showproblem.php?pid=5261
思路:
可以发现每个i都有一个取值半径,单调队列顺逆维护两遍就行了。
1 #define ios ios_base::sync_with_stdio(0); cin.tie(0); 2 #include <cstdio>//sprintf islower isupper 3 #include <cstdlib>//malloc exit strcat itoa system("cls") 4 #include <iostream>//pair 5 #include <fstream>//freopen("C:\\Users\\13606\\Desktop\\Input.txt","r",stdin); 6 #include <bitset> 7 //#include <map> 8 //#include<unordered_map> 9 #include <vector> 10 #include <stack> 11 #include <set> 12 #include <string.h>//strstr substr strcat 13 #include <string> 14 #include <time.h>// srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9; 15 #include <cmath> 16 #include <deque> 17 #include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less 18 #include <vector>//emplace_back 19 //#include <math.h> 20 #include <cassert> 21 #include <iomanip> 22 //#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor 23 #include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare) 24 using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation 25 //****************** 26 clock_t __START,__END; 27 double __TOTALTIME; 28 void _MS(){__START=clock();} 29 void _ME(){__END=clock();__TOTALTIME=(double)(__END-__START)/CLOCKS_PER_SEC;cout<<"Time: "<<__TOTALTIME<<" s"<<endl;} 30 //*********************** 31 #define rint register int 32 #define fo(a,b,c) for(rint a=b;a<=c;++a) 33 #define fr(a,b,c) for(rint a=b;a>=c;--a) 34 #define mem(a,b) memset(a,b,sizeof(a)) 35 #define pr printf 36 #define sc scanf 37 #define ls rt<<1 38 #define rs rt<<1|1 39 typedef pair<int,int> PII; 40 typedef vector<int> VI; 41 typedef unsigned long long ull; 42 typedef long long ll; 43 typedef double db; 44 const db E=2.718281828; 45 const db PI=acos(-1.0); 46 const ll INF=(1LL<<60); 47 const int inf=(1<<30); 48 const db ESP=1e-9; 49 const int mod=(int)1e9+7; 50 const int N=(int)1e6+10; 51 52 struct node 53 { 54 int l,r; 55 ll dis; 56 friend bool operator<(node a,node b) 57 { 58 if(a.dis==b.dis) 59 { 60 if(a.l==b.l) 61 return a.r<b.r; 62 return a.l<b.l; 63 } 64 return a.dis>b.dis; 65 } 66 }tans[N]; 67 struct tt 68 { 69 int pos; 70 ll dis; 71 }q[N]; 72 int cnt,have,tou; 73 int tot; 74 ll a[N]; 75 76 int TOT=0; 77 78 void solve() 79 { 80 pr("Case #%d:\n",++TOT); 81 tot=0; 82 int n; 83 ll R; 84 sc("%d%lld",&n,&R); 85 for(int i=1;i<=n;++i)sc("%lld",&a[i]),a[i+n]=a[i]; 86 int len=n/2; 87 n*=2; 88 tou=cnt=have=1; 89 q[1]={1,a[1]};//Case #1: 90 for(int i=2;i<=n;++i) 91 { 92 while(have&&abs(q[tou].pos-i)>len)tou++,have--; 93 tans[++tot]={q[tou].pos,i,q[tou].dis+a[i]+R*(i-q[tou].pos)}; 94 q[++cnt]={i,a[i]};have++; 95 for(int j=cnt;j>tou;--j) 96 { 97 if(q[j].dis>=q[j-1].dis+abs(i-q[j-1].pos)*R) 98 swap(q[j],q[j-1]),cnt--,have--; 99 else 100 break; 101 } 102 } 103 tou=cnt=have=1; 104 q[1]={n,a[n]}; 105 for(int i=n-1;i>=1;--i) 106 { 107 while(have&&abs(q[tou].pos-i)>len)tou++,have--; 108 tans[++tot]={i,q[tou].pos,q[tou].dis+a[i]+R*(q[tou].pos-i)}; 109 q[++cnt]={i,a[i]};have++; 110 for(int j=cnt;j>tou;--j) 111 { 112 if(q[j].dis>=q[j-1].dis+abs(i-q[j-1].pos)*R) 113 swap(q[j],q[j-1]),cnt--,have--; 114 else 115 break; 116 } 117 } 118 // sort(tans+1,tans+1+tot); 119 n/=2; 120 for(int i=1;i<=tot;++i) 121 { 122 tans[i].l=tans[i].l%n; 123 if(tans[i].l==0)tans[i].l=n; 124 tans[i].r=tans[i].r%n; 125 if(tans[i].r==0)tans[i].r=n; 126 if(tans[i].l>tans[i].r)swap(tans[i].l,tans[i].r); 127 } 128 sort(tans+1,tans+1+tot); 129 pr("%d %d\n",tans[1].l,tans[1].r); 130 } 131 132 int main() 133 { 134 int T; 135 sc("%d",&T); 136 while(T--)solve(); 137 return 0; 138 } 139 140 /**************************************************************************************/
以上是关于HDU5216--蜀道难(单调队列)的主要内容,如果未能解决你的问题,请参考以下文章
2018 Multi-University Training Contest 3 1001 / hdu6319 Problem A. Ascending Rating 单调队列,思维
HDU 6047 Maximum Sequence (贪心+单调队列)