• *UOJ#223. 【NOI2016】国王饮水记


    $n leq 8000$的数列,问不超过$m leq 1e9$次操作后第一个数字最大是多少。操作:选一些数,把他们变成他们的平均值。需要保留$p leq 3000$位小数,提供了一个小数高精度库。

    太长懒得写了。。总之就是个斜率优化DP,然后有奇怪性质

    原题解

    基本能猜到定理八,十至今没理解QAQ

    用前八个定理写了一份被卡精度的代码。就是DP的时候记决策点,然后最后用决策点算答案即可。但DP过程本身精度损得厉害,所以有些点过不了。

      1 // This is an empty program with decimal lib
      2 
      3 #include <stdio.h>
      4 #include <cstdlib>
      5 #include <cstring>
      6 #include <iostream>
      7 #include <string>
      8 #include <algorithm>
      9 //using namespace std;
     10 
     11 // ---------- decimal lib start ----------
     12 
     13 const int PREC = 3100;
     14 
     15 class Decimal {
     16     public:
     17         Decimal();
     18         Decimal(const std::string &s);
     19         Decimal(const char *s);
     20         Decimal(int x);
     21         Decimal(long long x);
     22         Decimal(double x);
     23         
     24         bool is_zero() const;
     25         
     26         // p (p > 0) is the number of digits after the decimal point
     27         std::string to_string(int p) const;
     28         double to_double() const;
     29         
     30         friend Decimal operator + (const Decimal &a, const Decimal &b);
     31         friend Decimal operator + (const Decimal &a, int x);
     32         friend Decimal operator + (int x, const Decimal &a);
     33         friend Decimal operator + (const Decimal &a, long long x);
     34         friend Decimal operator + (long long x, const Decimal &a);
     35         friend Decimal operator + (const Decimal &a, double x);
     36         friend Decimal operator + (double x, const Decimal &a);
     37         
     38         friend Decimal operator - (const Decimal &a, const Decimal &b);
     39         friend Decimal operator - (const Decimal &a, int x);
     40         friend Decimal operator - (int x, const Decimal &a);
     41         friend Decimal operator - (const Decimal &a, long long x);
     42         friend Decimal operator - (long long x, const Decimal &a);
     43         friend Decimal operator - (const Decimal &a, double x);
     44         friend Decimal operator - (double x, const Decimal &a);
     45         
     46         friend Decimal operator * (const Decimal &a, int x);
     47         friend Decimal operator * (int x, const Decimal &a);
     48         
     49         friend Decimal operator / (const Decimal &a, int x);
     50         
     51         friend bool operator < (const Decimal &a, const Decimal &b);
     52         friend bool operator > (const Decimal &a, const Decimal &b);
     53         friend bool operator <= (const Decimal &a, const Decimal &b);
     54         friend bool operator >= (const Decimal &a, const Decimal &b);
     55         friend bool operator == (const Decimal &a, const Decimal &b);
     56         friend bool operator != (const Decimal &a, const Decimal &b);
     57         
     58         Decimal & operator += (int x);
     59         Decimal & operator += (long long x);
     60         Decimal & operator += (double x);
     61         Decimal & operator += (const Decimal &b);
     62         
     63         Decimal & operator -= (int x);
     64         Decimal & operator -= (long long x);
     65         Decimal & operator -= (double x);
     66         Decimal & operator -= (const Decimal &b);
     67         
     68         Decimal & operator *= (int x);
     69         
     70         Decimal & operator /= (int x);
     71         
     72         friend Decimal operator - (const Decimal &a);
     73         
     74         // These can't be called
     75         friend Decimal operator * (const Decimal &a, double x);
     76         friend Decimal operator * (double x, const Decimal &a);
     77         friend Decimal operator / (const Decimal &a, double x);
     78         Decimal & operator *= (double x);
     79         Decimal & operator /= (double x);
     80         
     81     private:
     82         static const int len = PREC / 9 + 1;
     83         static const int mo = 1000000000;
     84         
     85         static void append_to_string(std::string &s, long long x);
     86         
     87         bool is_neg;
     88         long long integer;
     89         int data[len];
     90         
     91         void init_zero();
     92         void init(const char *s);
     93 };
     94 
     95 Decimal::Decimal() {
     96     this->init_zero();
     97 }
     98 
     99 Decimal::Decimal(const char *s) {
    100     this->init(s);
    101 }
    102 
    103 Decimal::Decimal(const std::string &s) {
    104     this->init(s.c_str());
    105 }
    106 
    107 Decimal::Decimal(int x) {
    108     this->init_zero();
    109     
    110     if (x < 0) {
    111         is_neg = true;
    112         x = -x;
    113     }
    114     
    115     integer = x;
    116 }
    117 
    118 Decimal::Decimal(long long x) {
    119     this->init_zero();
    120     
    121     if (x < 0) {
    122         is_neg = true;
    123         x = -x;
    124     }
    125     
    126     integer = x;
    127 }
    128 
    129 Decimal::Decimal(double x) {
    130     this->init_zero();
    131     
    132     if (x < 0) {
    133         is_neg = true;
    134         x = -x;
    135     }
    136     
    137     integer = (long long)x;
    138     x -= integer;
    139     
    140     for (int i = 0; i < len; i++) {
    141         x *= mo;
    142         if (x < 0) x = 0;
    143         data[i] = (int)x;
    144         x -= data[i];
    145     }
    146 }
    147 
    148 void Decimal::init_zero() {
    149     is_neg = false;
    150     integer = 0;
    151     memset(data, 0, len * sizeof(int));
    152 }
    153 
    154 bool Decimal::is_zero() const {
    155     if (integer) return false;
    156     for (int i = 0; i < len; i++) {
    157         if (data[i]) return false;
    158     }
    159     return true;
    160 }
    161 
    162 void Decimal::init(const char *s) {
    163     this->init_zero();
    164     
    165     is_neg = false;
    166     integer = 0;
    167     
    168     // find the first digit or the negative sign
    169     while (*s != 0) {
    170         if (*s == '-') {
    171             is_neg = true;
    172             ++s;
    173             break;
    174         } else if (*s >= 48 && *s <= 57) {
    175             break;
    176         }
    177         ++s;
    178     }
    179     
    180     // read the integer part
    181     while (*s >= 48 && *s <= 57) {
    182         integer = integer * 10 + *s - 48;
    183         ++s;
    184     }
    185     
    186     // read the decimal part
    187     if (*s == '.') {
    188         int pos = 0;
    189         int x = mo / 10;
    190         
    191         ++s;
    192         while (pos < len && *s >= 48 && *s <= 57) {
    193             data[pos] += (*s - 48) * x;
    194             ++s;
    195             x /= 10;
    196             if (x == 0) {
    197                 ++pos;
    198                 x = mo / 10;
    199             }
    200         }
    201     }
    202 }
    203 
    204 void Decimal::append_to_string(std::string &s, long long x) {
    205     if (x == 0) {
    206         s.append(1, 48);
    207         return;
    208     }
    209     
    210     char _[30];
    211     int cnt = 0;
    212     while (x) {
    213         _[cnt++] = x % 10;
    214         x /= 10;
    215     }
    216     while (cnt--) {
    217         s.append(1, _[cnt] + 48);
    218     }
    219 }
    220 
    221 std::string Decimal::to_string(int p) const {
    222     std::string ret;
    223     
    224     if (is_neg && !this->is_zero()) {
    225         ret = "-";
    226     }
    227     
    228     append_to_string(ret, this->integer);
    229     
    230     ret.append(1, '.');
    231     
    232     for (int i = 0; i < len; i++) {
    233         // append data[i] as "%09d"
    234         int x = mo / 10;
    235         int tmp = data[i];
    236         while (x) {
    237             ret.append(1, 48 + tmp / x);
    238             tmp %= x;
    239             x /= 10;
    240             if (--p == 0) {
    241                 break;
    242             }
    243         }
    244         if (p == 0) break;
    245     }
    246     
    247     if (p > 0) {
    248         ret.append(p, '0');
    249     }
    250     
    251     return ret;
    252 }
    253 
    254 double Decimal::to_double() const {
    255     double ret = integer;
    256     
    257     double k = 1.0;
    258     for (int i = 0; i < len; i++) {
    259         k /= mo;
    260         ret += k * data[i];
    261     }
    262     
    263     if (is_neg) {
    264         ret = -ret;
    265     }
    266     
    267     return ret;
    268 }
    269 
    270 bool operator < (const Decimal &a, const Decimal &b) {
    271     if (a.is_neg != b.is_neg) {
    272         return a.is_neg && (!a.is_zero() || !b.is_zero());
    273     } else if (!a.is_neg) {
    274         // a, b >= 0
    275         if (a.integer != b.integer) {
    276             return a.integer < b.integer;
    277         }
    278         for (int i = 0; i < Decimal::len; i++) {
    279             if (a.data[i] != b.data[i]) {
    280                 return a.data[i] < b.data[i];
    281             }
    282         }
    283         return false;
    284     } else {
    285         // a, b <= 0
    286         if (a.integer != b.integer) {
    287             return a.integer > b.integer;
    288         }
    289         for (int i = 0; i < Decimal::len; i++) {
    290             if (a.data[i] != b.data[i]) {
    291                 return a.data[i] > b.data[i];
    292             }
    293         }
    294         return false;
    295     }
    296 }
    297 
    298 bool operator > (const Decimal &a, const Decimal &b) {
    299     if (a.is_neg != b.is_neg) {
    300         return !a.is_neg && (!a.is_zero() || !b.is_zero());
    301     } else if (!a.is_neg) {
    302         // a, b >= 0
    303         if (a.integer != b.integer) {
    304             return a.integer > b.integer;
    305         }
    306         for (int i = 0; i < Decimal::len; i++) {
    307             if (a.data[i] != b.data[i]) {
    308                 return a.data[i] > b.data[i];
    309             }
    310         }
    311         return false;
    312     } else {
    313         // a, b <= 0
    314         if (a.integer != b.integer) {
    315             return a.integer < b.integer;
    316         }
    317         for (int i = 0; i < Decimal::len; i++) {
    318             if (a.data[i] != b.data[i]) {
    319                 return a.data[i] < b.data[i];
    320             }
    321         }
    322         return false;
    323     }
    324 }
    325 
    326 bool operator <= (const Decimal &a, const Decimal &b) {
    327     if (a.is_neg != b.is_neg) {
    328         return a.is_neg || (a.is_zero() && b.is_zero());
    329     } else if (!a.is_neg) {
    330         // a, b >= 0
    331         if (a.integer != b.integer) {
    332             return a.integer < b.integer;
    333         }
    334         for (int i = 0; i < Decimal::len; i++) {
    335             if (a.data[i] != b.data[i]) {
    336                 return a.data[i] < b.data[i];
    337             }
    338         }
    339         return true;
    340     } else {
    341         // a, b <= 0
    342         if (a.integer != b.integer) {
    343             return a.integer > b.integer;
    344         }
    345         for (int i = 0; i < Decimal::len; i++) {
    346             if (a.data[i] != b.data[i]) {
    347                 return a.data[i] > b.data[i];
    348             }
    349         }
    350         return true;
    351     }
    352 }
    353 
    354 bool operator >= (const Decimal &a, const Decimal &b) {
    355     if (a.is_neg != b.is_neg) {
    356         return !a.is_neg || (a.is_zero() && b.is_zero());
    357     } else if (!a.is_neg) {
    358         // a, b >= 0
    359         if (a.integer != b.integer) {
    360             return a.integer > b.integer;
    361         }
    362         for (int i = 0; i < Decimal::len; i++) {
    363             if (a.data[i] != b.data[i]) {
    364                 return a.data[i] > b.data[i];
    365             }
    366         }
    367         return true;
    368     } else {
    369         // a, b <= 0
    370         if (a.integer != b.integer) {
    371             return a.integer < b.integer;
    372         }
    373         for (int i = 0; i < Decimal::len; i++) {
    374             if (a.data[i] != b.data[i]) {
    375                 return a.data[i] < b.data[i];
    376             }
    377         }
    378         return true;
    379     }
    380 }
    381 
    382 bool operator == (const Decimal &a, const Decimal &b) {
    383     if (a.is_zero() && b.is_zero()) return true;
    384     if (a.is_neg != b.is_neg) return false;
    385     if (a.integer != b.integer) return false;
    386     for (int i = 0; i < Decimal::len; i++) {
    387         if (a.data[i] != b.data[i]) return false;
    388     }
    389     return true;
    390 }
    391 
    392 bool operator != (const Decimal &a, const Decimal &b) {
    393     return !(a == b);
    394 }
    395 
    396 Decimal & Decimal::operator += (long long x) {
    397     if (!is_neg) {
    398         if (integer + x >= 0) {
    399             integer += x;
    400         } else {
    401             bool last = false;
    402             for (int i = len - 1; i >= 0; i--) {
    403                 if (last || data[i]) {
    404                     data[i] = mo - data[i] - last;
    405                     last = true;
    406                 } else {
    407                     last = false;
    408                 }
    409             }
    410             integer = -x - integer - last;
    411             is_neg = true;
    412         }
    413     } else {
    414         if (integer - x >= 0) {
    415             integer -= x;
    416         } else {
    417             bool last = false;
    418             for (int i = len - 1; i >= 0; i--) {
    419                 if (last || data[i]) {
    420                     data[i] = mo - data[i] - last;
    421                     last = true;
    422                 } else {
    423                     last = false;
    424                 }
    425             }
    426             integer = x - integer - last;
    427             is_neg = false;
    428         }
    429     }
    430     return *this;
    431 }
    432 
    433 Decimal & Decimal::operator += (int x) {
    434     return *this += (long long)x;
    435 }
    436 
    437 Decimal & Decimal::operator -= (int x) {
    438     return *this += (long long)-x;
    439 }
    440 
    441 Decimal & Decimal::operator -= (long long x) {
    442     return *this += -x;
    443 }
    444 
    445 Decimal & Decimal::operator /= (int x) {
    446     if (x < 0) {
    447         is_neg ^= 1;
    448         x = -x;
    449     }
    450     
    451     int last = integer % x;
    452     integer /= x;
    453     
    454     for (int i = 0; i < len; i++) {
    455         long long tmp = 1LL * last * mo + data[i];
    456         data[i] = tmp / x;
    457         last = tmp - 1LL * data[i] * x;
    458     }
    459     
    460     if (is_neg && integer == 0) {
    461         int i;
    462         for (i = 0; i < len; i++) {
    463             if (data[i] != 0) {
    464                 break;
    465             }
    466         }
    467         if (i == len) {
    468             is_neg = false;
    469         }
    470     }
    471     
    472     return *this;
    473 }
    474 
    475 Decimal & Decimal::operator *= (int x) {
    476     if (x < 0) {
    477         is_neg ^= 1;
    478         x = -x;
    479     } else if (x == 0) {
    480         init_zero();
    481         return *this;
    482     }
    483     
    484     int last = 0;
    485     for (int i = len - 1; i >= 0; i--) {
    486         long long tmp = 1LL * data[i] * x + last;
    487         last = tmp / mo;
    488         data[i] = tmp - 1LL * last * mo;
    489     }
    490     integer = integer * x + last;
    491     
    492     return *this;
    493 }
    494 
    495 Decimal operator - (const Decimal &a) {
    496     Decimal ret = a;
    497     // -0 = 0
    498     if (!ret.is_neg && ret.integer == 0) {
    499         int i;
    500         for (i = 0; i < Decimal::len; i++) {
    501             if (ret.data[i] != 0) break;
    502         }
    503         if (i < Decimal::len) {
    504             ret.is_neg = true;
    505         }
    506     } else {
    507         ret.is_neg ^= 1;
    508     }
    509     return ret;
    510 }
    511 
    512 Decimal operator + (const Decimal &a, int x) {
    513     Decimal ret = a;
    514     return ret += x;
    515 }
    516 
    517 Decimal operator + (int x, const Decimal &a) {
    518     Decimal ret = a;
    519     return ret += x;
    520 }
    521 
    522 Decimal operator + (const Decimal &a, long long x) {
    523     Decimal ret = a;
    524     return ret += x;
    525 }
    526 
    527 Decimal operator + (long long x, const Decimal &a) {
    528     Decimal ret = a;
    529     return ret += x;
    530 }
    531 
    532 Decimal operator - (const Decimal &a, int x) {
    533     Decimal ret = a;
    534     return ret -= x;
    535 }
    536 
    537 Decimal operator - (int x, const Decimal &a) {
    538     return -(a - x);
    539 }
    540 
    541 Decimal operator - (const Decimal &a, long long x) {
    542     Decimal ret = a;
    543     return ret -= x;
    544 }
    545 
    546 Decimal operator - (long long x, const Decimal &a) {
    547     return -(a - x);
    548 }
    549 
    550 Decimal operator * (const Decimal &a, int x) {
    551     Decimal ret = a;
    552     return ret *= x;
    553 }
    554 
    555 Decimal operator * (int x, const Decimal &a) {
    556     Decimal ret = a;
    557     return ret *= x;
    558 }
    559 
    560 Decimal operator / (const Decimal &a, int x) {
    561     Decimal ret = a;
    562     return ret /= x;
    563 }
    564 
    565 Decimal operator + (const Decimal &a, const Decimal &b) {
    566     if (a.is_neg == b.is_neg) {
    567         Decimal ret = a;
    568         bool last = false;
    569         for (int i = Decimal::len - 1; i >= 0; i--) {
    570             ret.data[i] += b.data[i] + last;
    571             if (ret.data[i] >= Decimal::mo) {
    572                 ret.data[i] -= Decimal::mo;
    573                 last = true;
    574             } else {
    575                 last = false;
    576             }
    577         }
    578         ret.integer += b.integer + last;
    579         return ret;
    580     } else if (!a.is_neg) {
    581         // a - |b|
    582         return a - -b;
    583     } else {
    584         // b - |a|
    585         return b - -a;
    586     }
    587 }
    588 
    589 Decimal operator - (const Decimal &a, const Decimal &b) {
    590     if (!a.is_neg && !b.is_neg) {
    591         if (a >= b) {
    592             Decimal ret = a;
    593             bool last = false;
    594             for (int i = Decimal::len - 1; i >= 0; i--) {
    595                 ret.data[i] -= b.data[i] + last;
    596                 if (ret.data[i] < 0) {
    597                     ret.data[i] += Decimal::mo;
    598                     last = true;
    599                 } else {
    600                     last = false;
    601                 }
    602             }
    603             ret.integer -= b.integer + last;
    604             return ret;
    605         } else {
    606             Decimal ret = b;
    607             bool last = false;
    608             for (int i = Decimal::len - 1; i >= 0; i--) {
    609                 ret.data[i] -= a.data[i] + last;
    610                 if (ret.data[i] < 0) {
    611                     ret.data[i] += Decimal::mo;
    612                     last = true;
    613                 } else {
    614                     last = false;
    615                 }
    616             }
    617             ret.integer -= a.integer + last;
    618             ret.is_neg = true;
    619             return ret;
    620         }
    621     } else if (a.is_neg && b.is_neg) {
    622         // a - b = (-b) - (-a)
    623         return -b - -a;
    624     } else if (a.is_neg) {
    625         // -|a| - b
    626         return -(-a + b);
    627     } else {
    628         // a - -|b|
    629         return a + -b;
    630     }
    631 }
    632 
    633 Decimal operator + (const Decimal &a, double x) {
    634     return a + Decimal(x);
    635 }
    636 
    637 Decimal operator + (double x, const Decimal &a) {
    638     return Decimal(x) + a;
    639 }
    640 
    641 Decimal operator - (const Decimal &a, double x) {
    642     return a - Decimal(x);
    643 }
    644 
    645 Decimal operator - (double x, const Decimal &a) {
    646     return Decimal(x) - a;
    647 }
    648 
    649 Decimal & Decimal::operator += (double x) {
    650     *this = *this + Decimal(x);
    651     return *this;
    652 }
    653 
    654 Decimal & Decimal::operator -= (double x) {
    655     *this = *this - Decimal(x);
    656     return *this;
    657 }
    658 
    659 Decimal & Decimal::operator += (const Decimal &b) {
    660     *this = *this + b;
    661     return *this;
    662 }
    663 
    664 Decimal & Decimal::operator -= (const Decimal &b) {
    665     *this = *this - b;
    666     return *this;
    667 }
    668 
    669 // ---------- decimal lib end ----------
    670 
    671 int qread()
    672 {
    673     char c; int s=0; while ((c=getchar())<'0' || c>'9');
    674     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s;
    675 }
    676 #define lld Decimal
    677 #define ld long double
    678 int n,m,P;
    679 #define maxn 8011
    680 int a[maxn],sum[maxn];
    681 ld f[2][maxn]; short cur=0,p[maxn][maxn];
    682 short sta[maxn],top=0;
    683 
    684 struct Queue
    685 {
    686     int x; ld y;
    687     ld operator * (const Queue b) const {return (y-b.y)/(x-b.x);}
    688 }que[maxn]; int head,tail;
    689 
    690 ld calc(int i,int j) {return (f[cur][j]+sum[i]-sum[j])/(i-j+1);}
    691 
    692 int main()
    693 {
    694     n=qread(); m=qread(); P=qread();
    695     int a0=qread(); for (int i=1;i<n;i++) a[i]=qread();
    696     n--; {int m=0; for (int i=1;i<=n;i++) if (a[i]>a0) a[++m]=a[i]; n=m;}
    697     std::sort(a+1,a+1+n); for (int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];
    698     
    699     for (int i=0;i<=n;i++) f[0][i]=a0;
    700     ld ans=a0; short xx=0,yy=n;
    701     for (int i=1,to=std::min(n,m);i<=to;i++)
    702     {
    703         memset(f[cur^1],0,sizeof(f[cur^1]));
    704         f[cur^1][i]=(f[cur][i-1]+a[i])/2; p[i][i]=i-1;
    705         if (ans<f[cur^1][i]) ans=f[cur^1][i],xx=i,yy=i;
    706         head=tail=1; que[tail++]=(Queue){i-2,sum[i-1]-f[cur][i-1]};
    707         for (int j=i+1;j<=n;j++)
    708         {
    709             Queue u=(Queue){j-2,sum[j-1]-f[cur][j-1]};
    710             while (head<tail-1 && que[tail-1]*que[tail-2]>u*que[tail-1]) tail--;
    711             que[tail++]=u;
    712             while (head<tail-1 && calc(j,que[head].x+1)<calc(j,que[head+1].x+1)) head++;
    713             f[cur^1][j]=calc(j,que[head].x+1); p[i][j]=que[head].x+1;
    714             if (ans<f[cur^1][j]) ans=f[cur^1][j],xx=i,yy=j;
    715         }
    716         cur^=1;
    717     }
    718     
    719     lld Ans=lld(a0);
    720     for (;xx;yy=p[xx][yy],xx--) sta[++top]=yy; sta[++top]=yy;
    721     for (int i=top;i>1;i--) Ans=(Ans+(sum[sta[i-1]]-sum[sta[i]]))/(sta[i-1]-sta[i]+1);
    722     
    723     std::string s=Ans.to_string(P+2);
    724     std::cout<<s<<std::endl;
    725     return 0;
    726 }
    View Code
  • 相关阅读:
    CCF CSP 201403-2 窗口
    Ethical Hacking
    Ethical Hacking
    Ethical Hacking
    Ethical Hacking
    Ethical Hacking
    Ethical Hacking
    Ethical Hacking
    Ethical Hacking
    Ethical Hacking
  • 原文地址:https://www.cnblogs.com/Blue233333/p/9258425.html
Copyright © 2020-2023  润新知