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 单调队列,思维

hdu3530(单调队列)

HDU 3474 单调队列

HDU 6047 Maximum Sequence (贪心+单调队列)

HDU 3706 Second My Problem First (单调队列)

hdu 4193 单调队列