2 条题解
-
0
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N=2000005; LL sum[N],p[N],d[N],q[N],ok[N],n; template<typename T> void read(T& x) { x=0;char c=getchar();int f=1; for(;!isdigit(c);c=getchar())if(c=='-')f=-1; for(; isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48); x=x*f; } void DP1() { int l=1,r=0; for (int i=1; i<=n; ++i){ while (l<=r && sum[q[r]]>=sum[i]) --r; q[++r]=i; } /* 思路:当前枚举到i,点(i-n)和i是同个点,那么研究 (i-n)->i能否顺利一圈。 判断方法:只要 sum[i-n+1]~sum[i]的 任意一个都大于等于sum[i-n]即可 sum[i-n+1]~sum[i]中的最小值是sum[q[l]],所以只要判断 sum[q[l]]>=sum[i-n]即可证明。 */ for (int i=n+1; i<=n*2; ++i){ while (l<=r && sum[q[r]]>=sum[i]) --r; q[++r]=i; while (l<=r && q[l]<=i-n) ++l; if(sum[q[l]]-sum[i-n]>=0) ok[i-n]=1; } } void DP2() { int l=1,r=0; for (int i=n*2; i>n; --i){ while(l<=r && sum[q[r]]>=sum[i]) --r; q[++r]=i; } for (int i=n; i; --i){ while(l<=r && sum[q[r]]>=sum[i]) --r; q[++r]=i; while(l<=r && q[l]>=i+n) ++l; if (sum[q[l]]-sum[i+n]>=0) ok[i]=1; } } int main() { read(n); sum[0]=p[0]=d[0]=0; for (int i=1; i<=n; ++i) { read(p[i]);p[i+n]=p[i]; read(d[i]);d[i+n]=d[i]; sum[i]=sum[i-1]+p[i-1]-d[i-1]; } for (int i=n+1; i<=n*2; ++i)sum[i]=sum[i-1]+p[i-1]-d[i-1]; //sum[i]表示达到i点的汽油存量 DP1(); for (int i=n*2; i; --i) sum[i]=sum[i+1]+p[i+1]-d[i]; DP2(); for (int i=1; i<=n; ++i) printf("%s\n",ok[i]?"TAK":"NIE"); return 0; } -
0
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N=2000005; LL sum[N],p[N],d[N],q[N],ok[N],n; template<typename T> void read(T& x) { x=0;char c=getchar();int f=1; for(;!isdigit(c);c=getchar())if(c=='-')f=-1; for(; isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48); x=x*f; } void DP1() { int l=1,r=0; for (int i=1; i<=n; ++i){ while (l<=r && sum[q[r]]>=sum[i]) --r; q[++r]=i; } /* 思路:当前枚举到i,点(i-n)和i是同个点,那么研究 (i-n)->i能否顺利一圈。 判断方法:只要 sum[i-n+1]~sum[i]的 任意一个都大于等于sum[i-n]即可 sum[i-n+1]~sum[i]中的最小值是sum[q[l]],所以只要判断 sum[q[l]]>=sum[i-n]即可证明。 */ for (int i=n+1; i<=n*2; ++i){ while (l<=r && sum[q[r]]>=sum[i]) --r; q[++r]=i; while (l<=r && q[l]<=i-n) ++l; if(sum[q[l]]-sum[i-n]>=0) ok[i-n]=1; } } void DP2() { int l=1,r=0; for (int i=n*2; i>n; --i){ while(l<=r && sum[q[r]]>=sum[i]) --r; q[++r]=i; } for (int i=n; i; --i){ while(l<=r && sum[q[r]]>=sum[i]) --r; q[++r]=i; while(l<=r && q[l]>=i+n) ++l; if (sum[q[l]]-sum[i+n]>=0) ok[i]=1; } } int main() { read(n); sum[0]=p[0]=d[0]=0; for (int i=1; i<=n; ++i) { read(p[i]);p[i+n]=p[i]; read(d[i]);d[i+n]=d[i]; sum[i]=sum[i-1]+p[i-1]-d[i-1]; } for (int i=n+1; i<=n*2; ++i)sum[i]=sum[i-1]+p[i-1]-d[i-1]; //sum[i]表示达到i点的汽油存量 DP1(); for (int i=n*2; i; --i) sum[i]=sum[i+1]+p[i+1]-d[i]; DP2(); for (int i=1; i<=n; ++i) printf("%s\n",ok[i]?"TAK":"NIE"); return 0; }
- 1
信息
- ID
- 3188
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 7
- 标签
- 递交数
- 30
- 已通过
- 9
- 上传者