题意:给定N,L,P,求f[N]

sum[i]递增,L<=3e6,P<=10
思路:四边形不等式的证明见https://www.byvoid.com/zhs/blog/noi-2009-poet
1 #include<bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 typedef unsigned int uint;
5 typedef unsigned long long ull;
6 typedef long double ld;
7 typedef pair<int,int> PII;
8 typedef pair<ll,ll> Pll;
9 typedef vector<int> VI;
10 typedef vector<PII> VII;
11 //typedef pair<ll,ll>P;
12 #define N 300010
13 #define M 200010
14 #define INF 1e18
15 #define fi first
16 #define se second
17 #define MP make_pair
18 #define pb push_back
19 #define pi acos(-1)
20 #define mem(a,b) memset(a,b,sizeof(a))
21 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
22 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
23 #define lowbit(x) x&(-x)
24 #define Rand (rand()*(1<<16)+rand())
25 #define id(x) ((x)<=B?(x):m-n/(x)+1)
26 #define ls p<<1
27 #define rs p<<1|1
28
29 const //ll MOD=1e9+7,inv2=(MOD+1)/2;
30 double eps=1e-6;
31 //int INF=1e9;
32 int dx[4]={-1,1,0,0};
33 int dy[4]={0,0,-1,1};
34
35 struct node
36 {
37 int l,r,id;
38 }q[N];
39
40 int n,L,P;
41 ld dp[N],s[N];
42 char ch[100];
43
44 int read()
45 {
46 int v=0,f=1;
47 char c=getchar();
48 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
49 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
50 return v*f;
51 }
52
53 ld pw(ld x)
54 {
55 if(x<0) x=-x;
56 ld ans=1;
57 rep(i,1,P) ans*=x;
58 return ans;
59 }
60
61 ld calc(int j,int i)
62 {
63 return dp[j]+pw(s[i]-s[j]-L+i-j-1);
64 }
65
66 void solve()
67 {
68 n=read(),L=read(),P=read();
69 s[0]=0;
70 rep(i,1,n)
71 {
72 scanf("%s",ch+1);
73 int x=strlen(ch+1);
74 s[i]=s[i-1]+x;
75 }
76 int h=0,t=0,l,r,last;
77 q[0]={1,n,0};
78 rep(i,1,n)
79 {
80 while(i>q[h].r) h++;
81 dp[i]=calc(q[h].id,i);
82 if(calc(i,n)>calc(q[t].id,n)) continue;
83 while(i<q[t].l&&calc(i,q[t].l)<calc(q[t].id,q[t].l)) t--;
84 l=max(q[t].l,i+1);
85 r=q[t].r;
86 last=min(n,q[t].r+1);
87 while(l<=r)
88 {
89 int mid=(l+r)>>1;
90 if(calc(i,mid)<calc(q[t].id,mid)){last=mid; r=mid-1;}
91 else l=mid+1;
92 }
93 q[t].r=last-1;
94 q[++t]={last,n,i};
95 }
96 if(dp[n]>INF) printf("Too hard to arrange\n");
97 else printf("%lld\n",(ll)dp[n]);
98 printf("--------------------\n");
99 }
100
101 int main()
102 {
103 int cas=read();
104 while(cas--) solve();
105 return 0;
106 }