1600 旅行计划
单调队列优化DP
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read()
{
ll s=0;
bool f=0;
char ch=' ';
while(!isdigit(ch))
{
f|=(ch=='-');
ch=getchar();
}
while(isdigit(ch))
{
s=(s<<3)+(s<<1)+(ch^48);
ch=getchar();
}
return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x<10)
{
putchar(x+'0');
return;
}
write(x/10);
putchar((x%10)+'0');
return;
}
inline void writeln(ll x)
{
write(x);
putchar('\n');
return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) writeln(x)
const int N=1000005;
int n,You[N<<1],Dis[N<<1],You1[N<<2],Dis1[N<<1],Oil[N<<1];
ll Sum[N<<1];
bool ans[N<<1];
struct Data
{
ll Shuz;
int Weiz;
}Ddq[N<<1];
int main()
{
int i,Head,Tail;
R(n);
for(i=1;i<=n;i++)
{
You[i]=You[i+n]=read();
Dis[i]=Dis[i+n]=read();
Oil[i]=Oil[i+n]=You[i]-Dis[i];
}
Head=1; Tail=0;
for(i=1;i<=n+n;i++)
{
Sum[i]=Sum[i-1]+Oil[i];
while(Head<Tail&&Ddq[Head].Weiz<i-n+1) Head++;
if(i>=n)
{
if(Ddq[Head].Shuz-Sum[i-n]<0) ans[i-n+1]=0;
else ans[i-n+1]=1;
}
while(Head<=Tail&&Ddq[Tail].Shuz>Sum[i]) Tail--;
Ddq[++Tail]=(Data){Sum[i],i};
}
for(i=1;i<=n;i++)
{
You1[i]=You[n-i+2];
Dis1[i]=Dis[n-i+1];
Oil[i]=Oil[i+n]=You1[i]-Dis1[i];
}
Head=1; Tail=0;
for(i=1;i<=n+n;i++)
{
Sum[i]=Sum[i-1]+Oil[i];
while(Head<Tail&&Ddq[Head].Weiz<i-n+1) Head++;
if(i>=n)
{
if(Ddq[Head].Shuz-Sum[i-n]>=0)
{
(i==n)?(ans[1]=1):(ans[n-(i-n+1)+2]=1);
}
}
while(Head<=Tail&&Ddq[Tail].Shuz>Sum[i]) Tail--;
Ddq[++Tail]=(Data){Sum[i],i};
}
for(i=1;i<=n;i++)
{
(ans[i])?puts("TAK"):puts("NIE");
}
return 0;
}