[Luogu5665] divided

DP violence, with a front number i f [i] [j], is the last interval (J, i] minimum answer, transfer equation can be used to optimize the prefix and complexity of $ o (n ^ 3) $
(may then be optimized to various $ o (n ^ 2) $ , but does not require)
the output f [i] [j], can be found if the f [i] [j-1 ] , and f [i] [j ] legitimate, then $ f [i] [j] \ le f [i] [j-1] $
proof: the number of return, considering so f [i] [j] and f [i] [j-1 ] are legitimate , set f [i] [j-1 ] a f [j-1] [k ] transfer, f [i] [j] from the f [i] [k '] transfer, there must be $ k \ le k' $ , i.e. to the left can be removed several number (may be 0) to ensure that legitimate
in such a strategy is divided f [i] [j-1 ], and the divided section provided are $ S1 \ le S2 \ le ... ... \ le St $, and respectively left remove Li, the right added Ri, clearly $ L1 = Rt = 0 $ and $ R_ {i-1} = Li $, then the interval and from $ \ sum_ {i = 1} ^ {t} Si ^ {2 } $ into $ \ sum_ {i = 1} ^ {t} (Si + Ri-Li) ^ 2 = \ sum_ {i = 1} ^ {t} Si ^ 2 + \ sum_ {i = 1} ^ { t} (Ri-R_ {i-1}) ^ {2} +2 \ sum_ {i = 1} ^ {t} Si (Ri-R_ {i-1}) \ le \ sum_ {i = 1} ^ {t} Si ^ 2 + 2 \ sum_ {i = 1} ^ {t} Ri (Si-S_ {i-1}) \ le \ sum_ {i = 1} ^ {t } Si ^ 2 $
through proof, can be obtained at the same time how to construct the optimal solution, dried priority queue Maintain the last legitimate, then select from the n forward to
need to write on the test precision (lazy to use the __int128)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define mod (1<<30)
 4 #define N 40000007
 5 #define ll long long
 6 #define lll __int128
 7 int n,type,m,x,y,z,q[N],f[N],b[N];
 8 ll ans,a[N];
 9 ll calc(int k){
10     return 2*a[k]-a[f[k]];
11 }
12 void write(lll k){
13     if (k>9)write(k/10);
14     putchar(k%10+'0');
15 }
16 int main(){
17     scanf("%d%d",&n,&type);
18     if (!type)
19         for(int i=1;i<=n;i++){
20             scanf("%d",&x);
21             a[i]=a[i-1]+x;
22         }
23     else{
24         scanf("%d%d%d%d%d%d",&x,&y,&z,&b[1],&b[2],&m);
25         for(int i=3;i<=n;i++)b[i]=(1LL*x*b[i-1]+1LL*y*b[i-2]+z)%mod;
26         int xx=1;
27         for(int i=1;i<=m;i++){
28             scanf("%d%d%d",&x,&y,&z);
29             for(int j=xx;j<=x;j++)a[j]=a[j-1]+b[j]%(z-y+1)+y;
30             xx=x+1;
31         }
32     }
33     x=1;
34     y=0;
35     for(int i=1;i<=n;i++){
36         while ((x<=y)&&(calc(q[x])<=a[i]))x++;
37         f[i]=q[x-1];
38         while ((x<=y)&&(calc(q[y])>=calc(i)))y--;
39         q[++y]=i;
40     }
41     lll ans=0,o=1;
42     for(int i=n;i;i=f[i])ans+=o*(a[i]-a[f[i]])*(a[i]-a[f[i]]);
43     write(ans);
44 }
View Code

 

Guess you like

Origin www.cnblogs.com/PYWBKTDA/p/11901307.html