E47 单调队列优化DP 旅行问题

E47 单调队列优化DP 旅行问题_哔哩哔哩_bilibili

 

U230380 [POI2004] 旅行问题 - 洛谷

U126668 【一本通 5.5 例 4】 旅行问题 - 洛谷

// 单调队列+前缀和 O(n)
#include<iostream>
using namespace std;

const int N=2000010;
int n,oil[N],dis[N],q[N];
long long s[N];
bool flag[N];

int main(){
  cin>>n;
  for(int i=1;i<=n;i++){
    cin>>oil[i]>>dis[i];
    s[i]=s[i+n]=oil[i]-dis[i];
  }
  for(int i=1;i<=2*n;i++) s[i]+=s[i-1]; //前缀和
  
  for(int i=2*n,h=1,t=0; i>=1; i--){ //顺时针行驶
    while(h<=t && q[h]>i+n-1) h++;
    while(h<=t && s[q[t]]>=s[i]) t--;
    q[++t]=i;
    if(i<=n && s[q[h]]-s[i-1]>=0) flag[i]=true;
  }
  
  dis[0]=dis[n];
  for(int i=n;i;i--) s[i]=s[i+n]=oil[i]-dis[i-1];
  for(int i=2*n;i;i--) s[i]+=s[i+1]; //后缀和
  
  for(int i=1,h=1,t=0; i<=2*n; i++){  //逆时针行驶
    while(h<=t && q[h]<i-n+1) h++;
    while(h<=t && s[q[t]]>=s[i]) t--;
    q[++t]=i;
    if(i>n && s[q[h]]-s[i+1]>=0) flag[i-n]=true;
  }
  
  for(int i=1;i<=n;i++) puts(flag[i]?"TAK":"NIE");
}

 

posted @ 2023-04-29 14:13  董晓  阅读(448)  评论(0)    收藏  举报