zoukankan      html  css  js  c++  java
  • loj 10178 POI2004 旅行问题

    传送门:loj 10178

    分析

    因为是环形,开两倍

    油量 - 到下一个站的距离 = 剩余油量

    如果在一圈之中有哪一个时刻的前缀和小于零,那么这一点不能作为起点(sum[j] - sum[i-1]<0,i为起点,j为其他站点)

    所以sum[j]需要大于sum[i]

    可以用单调队列优化:长度限制为n,sum单调递增

    如果队首 + n等于当前编号,则已经一圈了,标记为1

    代码

     1 /****************************
     2 User:Mandy.H.Y
     3 Language:c++
     4 Problem:
     5 Algorithm:
     6 Date:
     7 ****************************/
     8 #include<bits/stdc++.h>
     9 
    10 using namespace std;
    11 
    12 const int maxn = 1e6 + 5;
    13 
    14 int n,l,r;
    15 long long sum[maxn];
    16 long long p[maxn<<1],p1[maxn << 1];
    17 //p顺时针,p1逆时针 
    18 int q[maxn];
    19 bool vis[maxn];
    20 
    21 template<class T>inline void read(T &x){
    22     x = 0;bool flag = 0;char ch = getchar();
    23     while(!isdigit(ch)) flag |= ch == '-',ch = getchar();
    24     while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar();
    25     if(flag) x = -x;
    26 }
    27 
    28 template<class T>void putch(const T x){
    29     if(x > 9) putch(x / 10);
    30     putchar(x % 10 | 48);
    31 } 
    32 
    33 template<class T>void put(const T x){
    34     if(x < 0) putchar('-'),putch(-x);
    35     else putch(x);
    36 }
    37 
    38 void file(){
    39     freopen("data3.in","r",stdin);
    40 //    freopen("10178.out","w",stdout);
    41 }
    42 
    43 void readdata(){
    44     read(n);
    45     long long d,pre = 0;
    46     for(int i = 1;i <= n; ++ i){
    47         read(p[i]);p1[i] = p[i];
    48         read(d);
    49         p[i] -= d;//油量 - 距离 = 剩余油量 
    50         p1[i] -= pre;
    51         p1[i + n] = p1[i];//环形开两倍 
    52         p[i + n] = p[i];
    53         pre = d;
    54     }
    55     p1[1] -= pre;
    56     p1[n + 1] = p1[1];//逆时针1减去n 
    57 }
    58 
    59 void work(){
    60     //保证sum单调递增,不然油量会剩余负
    61     //以i为起点走到j的剩余油量:sum[j] - sum[i-1]; 
    62     for(int i = 1;i <= n + n; ++ i){//顺时针 
    63         while(l < r && q[l] + n == i) vis[q[l]] = 1,l++;//看是否一圈完毕 
    64         sum[i] = sum[i-1] + p[i];//前缀和 
    65 //        while(l < r && sum[i] - sum[q[l] - 1] < 0) l++;
    66         while(l < r && sum[i] - sum[q[r - 1] - 1] < 0) r--;
    67         //后面的油量剩余为负 ,则弹出 
    68         //记得 - 1 :q[r - 1] - 1 
    69         if(p[i] >= 0) q[r++] = i;//如果本身为负,不能作为起点 
    70     }
    71 
    72     l = r = 0;
    73     sum[n + n + 1] = 0;//清空 
    74 
    75     for(int i = n + n;i >= 1; -- i){//逆时针 
    76         while(l < r && q[l] - n == i) vis[q[l] - n] = 1,l++;
    77         sum[i] = sum[i+1] + p1[i];//用p1 
    78 //        while(l < r && sum[i] - sum[q[l] + 1] < 0) l++;
    79         while(l < r && sum[i] - sum[q[r - 1] + 1] < 0) r--;//记得要 + 1 ,是  < 
    80         if(p1[i] >= 0) q[r++] = i;        
    81     }
    82     
    83     for(int i = 1;i <= n; ++ i){
    84         if(vis[i]) puts("TAK");
    85         else puts("NIE");
    86     }
    87 }
    88 
    89 int main(){
    90 //    file();
    91     readdata();
    92     work();
    93     return 0;
    94 }
    View Code
    非做顽石不可,哪管他敬仰暗唾
  • 相关阅读:
    劳动节CF题总结
    「联合省选 2020 A」作业题 做题心得
    bzoj3784 树上的路径
    [AGC039E] Pairing Points
    [AGC012E] Camel and Oases
    [AGC011F] Train Service Planning
    [AGC039F] Min Product Sum
    Pedersen commitment原理
    标准模型(standard model)与随机语言模型(random oracle model)
    会议论文引用缩写标准 PDF
  • 原文地址:https://www.cnblogs.com/Mandy-H-Y/p/11435837.html
Copyright © 2011-2022 走看看