记录编号 61898 评测结果 AAAAAAAAAA
题目名称 [NOI 2009]诗人小G 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 2.627 s
提交时间 2013-06-17 19:27:33 内存使用 3.46 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<deque>
#include<iomanip>
#include<cstring>
#include<stack>
#include<fstream>
using namespace std;
typedef long long ll;
typedef long double ld;
ifstream fin("noi09_poet.in");
ofstream fout("noi09_poet.out");
const ll SIZEN=100001;
const ld LIM=1e18;
ld S[SIZEN]={0};
ld f[SIZEN]={0};
ll N,L,C,P;
string word[SIZEN];
bool el[SIZEN]={0};//"转折点"
ld labs(ld x){
	return x>0?x:-x;
}
ld pow(ld x){//x^P
	ld ans=1;
	ll i;
	for(i=1;i<=P;i++) ans*=x;
	return labs(ans);
}
ld fig(ll x,ll i){//在状态x下的决策i
	return f[i]+pow(S[x]-S[i]-C);
}
ll find(ll s,ll e,ll x,ll y){//在区间[s,e]上使得决策y优于决策x的最小值
	if(s==e){
		if(fig(s,y)<=fig(s,x)) return s;
		else return s+1;
	}
	ll mid=(s+e)>>1;
	if(fig(mid,x)>=fig(mid,y)) return find(s,mid,x,y);
	else return find(mid+1,e,x,y);
}
int jc[SIZEN]={0};//每个点的决策
class TRI{
public:
	ll pos;//决策值
	ll s,e;//起点和终点
};
class MNQ{
public:
	deque<TRI> lis;
	void clear(void){
		lis.clear();
	}
	void clf(ll x){//把x之前(不含)的决策全部删除
		while(lis.size()&&lis.front().e<x) lis.pop_front();
	}
	void update(ll x){//用决策x-1更新区间并且更新x的决策,如果大于1e18就false
		clf(x);
		lis[0].s=x;
		TRI temp=lis.front();
		int nows;
		while(lis.size()&&fig(lis.back().s,x-1)<=fig(lis.back().s,lis.back().pos)){
			nows=lis.back().s;
			lis.pop_back();
		}
		if(lis.size()&&fig(lis.back().e,x-1)<=fig(lis.back().e,lis.back().pos)){
			if(fig(lis.back().e,x-1)<=fig(lis.back().e,lis.back().pos)){
				int now=find(lis.back().s,lis.back().e,lis.back().pos,x-1);
				lis.back().e=now-1;
				nows=now;
			}
		}
		if(lis.size()==0||lis.back().e<N) lis.push_back((TRI){x-1,nows,N});
		clf(x);
		jc[x]=lis[0].pos;
		f[x]=fig(x,jc[x]);
	}
}Q;
void process(void){
	ll i;
	Q.lis.push_back((TRI){0,1,N});
	for(i=1;i<=N;i++) Q.update(i);
	if(f[N]>LIM) goto END;
	fout<<(ll)f[N]<<endl;
	int x;
	x=N;
	while(x){
		x=jc[x];
		if(x) el[x]=true;
	}
	for(i=1;i<=N;i++){
		fout<<word[i];
		fout<<(el[i]?"\n":" ");
	}
	fout<<endl<<"--------------------"<<endl;
	return;
	END:;
	fout<<"Too hard to arrange";
	fout<<endl<<"--------------------"<<endl;
	return;
}
void init(void){
	fin>>N>>L>>P;
	C=L+1;
	string str;
	ll i;
	for(i=1;i<=N;i++){
		fin>>str;
		word[i]=str;
		S[i]=str.size();
		S[i]+=S[i-1];
	}
	for(i=1;i<=N;i++) S[i]+=i;
	f[0]=0;
	Q.clear();
	memset(el,0,sizeof(el));
}
int main(){
	int T;
	fin>>T;
	while(T){
		init();
		process();
		T--;
	}
	fin.close();
	fout.close();
	return 0;
}