20200529小結(中)

太長了,分開來發博客

20200522B農民

題意:有一棵權值不合法的二叉搜索樹,帶權值修改,子樹翻轉,查詢點u在訪問其權值a[u]是能否被找到

題解:

一個點u能在查詢a[u]時被訪問到,必須滿足由根到它的路徑上的祖先的權值的大小範圍限制

把每一個點的權值看做分別對左右子樹的限制,維護小於限制的最大值與大於限制的最小值,以及翻轉後的這兩個值

有一定的細節:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int gi()
{
	char c;int num=0,flg=1;
	while((c=getchar())<'0'||c>'9')if(c=='-')flg=-1;
	while(c>='0'&&c<='9'){num=num*10+c-48;c=getchar();}
	return num*flg;
}
#define N 100005
int fa[N],ch[N][2];
int son[N],siz[N],top[N];
int dfn[N],num[N],dc;
void dfs1(int u)
{
	siz[u]=1;
	for(int v,i=0;i<2;i++){
		if((v=ch[u][i])){
			dfs1(v);siz[u]+=siz[v];
			if(siz[son[u]]<siz[v])son[u]=v;
		}
	}
}
void dfs2(int u)
{
	dfn[u]=++dc;num[dc]=u;
	if(son[u])top[son[u]]=top[u],dfs2(son[u]);
	for(int v,i=0;i<2;i++)
		if((v=ch[u][i])&&v!=son[u])
			top[v]=v,dfs2(v);
}
#define lc i<<1
#define rc i<<1|1
const int INF=0x3f3f3f3f;
int val[N],mx[N<<2][2],mi[N<<2][2];bool rev[N<<2];
struct node{int l,r;}a[N<<2];
void pushup(int i)
{
	mi[i][0]=min(mi[lc][0],mi[rc][0]);
	mx[i][0]=max(mx[lc][0],mx[rc][0]);
	mi[i][1]=min(mi[lc][1],mi[rc][1]);
	mx[i][1]=max(mx[lc][1],mx[rc][1]);
}
void rever(int i)
{
	rev[i]^=1;
	swap(mi[i][0],mi[i][1]);
	swap(mx[i][0],mx[i][1]);
}
void pushdown(int i)
{
	if(rev[i]){
		rever(lc),rever(rc);
		rev[i]=0;
	}
}
void build(int i,int l,int r)
{
	a[i].l=l;a[i].r=r;
	mi[i][0]=mi[i][1]=INF;
	mx[i][0]=mx[i][1]=-INF;
	if(l==r){
		int u=num[l];
		if(fa[u]){
			if(ch[fa[u]][0]==u)
				mi[i][0]=mx[i][1]=val[fa[u]];
			else
				mx[i][0]=mi[i][1]=val[fa[u]];
		}
		return;
	}
	int mid=(l+r)>>1;
	build(lc,l,mid);build(rc,mid+1,r);
	pushup(i);
}
void fresh(int i,int x)
{
	if(a[i].l>x||a[i].r<x)return;
	if(a[i].l==a[i].r){
		int u=num[x];
		if(fa[u]){
			mi[i][0]=mi[i][1]=INF;
			mx[i][0]=mx[i][1]=-INF;
			if((ch[fa[u]][0]==u)^rev[i])
				mi[i][0]=mx[i][1]=val[fa[u]];
			else
				mx[i][0]=mi[i][1]=val[fa[u]];
		}
		return;
	}
	pushdown(i);
	fresh(lc,x);fresh(rc,x);
	pushup(i);
}
void modify(int x,int k)
{
	val[x]=k;
	if(ch[x][0])fresh(1,dfn[ch[x][0]]);
	if(ch[x][1])fresh(1,dfn[ch[x][1]]);
}
void insert(int i,int l,int r)
{
	if(a[i].l>r||a[i].r<l)return;
	if(l<=a[i].l&&a[i].r<=r){rever(i);return;}
	pushdown(i);
	insert(lc,l,r);insert(rc,l,r);
	pushup(i);
}
int X;
bool query(int i,int l,int r)
{
	if(a[i].l>r||a[i].r<l)return 1;
	if(l<=a[i].l&&a[i].r<=r)
		return (X>mx[i][0]&&X<mi[i][0]);
	pushdown(i);
	return query(lc,l,r)&query(rc,l,r);
}
int rt;
bool QP(int x)
{
	bool ret=1;X=val[x];
	while(x){
		ret&=query(1,dfn[top[x]],dfn[x]);
		x=fa[top[x]];
	}
	return ret;
}
int main()
{
	int n,Q,i,op,x,k;
	n=gi();Q=gi();
	for(i=1;i<=n;i++){
		val[i]=gi();ch[i][0]=gi();ch[i][1]=gi();
		if(ch[i][0])fa[ch[i][0]]=i;
		if(ch[i][1])fa[ch[i][1]]=i;
	}
	for(i=1;i<=n;i++)if(!fa[i]){rt=i;break;}
	dfs1(rt);top[rt]=rt;dfs2(rt);
	build(1,1,n);
	while(Q--){
		op=gi();x=gi();
		if(op==1){k=gi();modify(x,k);}
		else if(op==2)insert(1,dfn[x]+1,dfn[x]+siz[x]-1);
		else{
			if(QP(x))printf("YES\n");
			else printf("NO\n");
		}
	}
}

 

 

 

20200523C、祕密行動

image image 

題解:

看了好久的題纔算看懂了

取對數+最小割

把10個質數分別拆成50個點向源點匯點連邊,邊權爲c、d,表示它是否存在於a[i]中

m組關係實際上就是在某兩個點之間連一條權值爲f的邊

要求乘積最小可以先把邊權取log,做完最大流之後exp回去即可

代碼:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 505
#define M 50005
int fir[N],to[M],nxt[M],cnt;
double cap[M],f[15];
void adde(int a,int b,double c,double d)
{
	to[++cnt]=b;nxt[cnt]=fir[a];fir[a]=cnt;cap[cnt]=c;
	to[++cnt]=a;nxt[cnt]=fir[b];fir[b]=cnt;cap[cnt]=d;
}
int S,T,sz;
int d[N],vd[N];
const double eps=1e-6;
double sap(int u,double aug)
{
	if(u==T)return aug;
	int mind=sz-1;double ret=0,tmp;
	for(int v,p=fir[u];p;p=nxt[p]){
		if(cap[p]>0){
			v=to[p];
			if(d[u]==d[v]+1){
				tmp=sap(v,min(aug,cap[p]));
				cap[p]-=tmp;aug-=tmp;
				cap[p^1]+=tmp;ret+=tmp;
				if(d[S]>=sz)break;
				if(aug==0)return ret;
			}
			mind=min(mind,d[u]);
		}
	}
	if(fabs(ret)<eps){
		vd[d[u]]--;
		if(vd[d[u]]==0)
			d[S]=sz;
		d[u]=mind+1;
		vd[d[u]]++;
	}
	return ret;
}
double flow;
void maxflow()
{
	memset(d,0,sizeof(d));
	memset(vd,0,sizeof(vd));
	vd[0]=sz;
	while(d[S]<sz)
		flow+=sap(S,1e9);
}
int main()
{
	cnt=1;
	int n,m,i,j,u,v,c,x;
	double w;
	scanf("%d%d",&n,&m);
	for(i=1;i<=10;i++)
		scanf("%d%lf",&x,&f[i]);
	S=n*10+1;T=n*10+2;sz=T;
	for(i=1;i<=n;i++){
		u=i;
		for(j=1;j<=10;j++){
			scanf("%lf",&w);
			adde(S,(u-1)*10+j,log(w),0);
		}
		for(j=1;j<=10;j++){
			scanf("%lf",&w);
			adde((u-1)*10+j,T,log(w),0);
		}
	}
	for(i=1;i<=m;i++){
		scanf("%d%d%d",&u,&v,&c);
		adde((u-1)*10+c,(v-1)*10+c,log(f[c]),log(f[c]));
	}
	maxflow();
	printf("%.5f\n",exp(flow));
}

 

 

20200525A. 數據結構

題意:一個長度爲n的序列,帶修改,查一些區間的和的歷史最小值,可以離線

題解:

我們一般可以用線段樹來解決區間加、單點(實際上是線段樹上所有節點對應的區間)查詢歷史最小值

如果把詢問離線下來,把一個詢問l,r看成一個座標爲(l,r)的點

那麼一個修改就是在一個矩形區域((1,l),(r,n))裏修改,單點查詢歷史最小值

可以想到用KD樹來解決

在KD樹上的節點維護四個標記minx,miad,val,ad

分別表示該點對應的歷史最小值,歷史最小增量(歷史最小的ad),當前的實際值,加法標記

那麼更新方法是顯然的

minx=min(minx,val+pmiad)

miad=min(miad,ad+pmiad)

val+=pad   ad+=ad

代碼:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int gi()
{
	char c;int num=0,flg=1;
	while((c=getchar())<'0'||c>'9')if(c=='-')flg=-1;
	while(c>='0'&&c<='9'){num=num*10+c-48;c=getchar();}
	return num*flg;
}
#define N 100005
#define LL long long
#define lc ch[i][0]
#define rc ch[i][1]
int ch[N][2],fa[N];
int a[N][2],mx[N][2],mi[N][2];
int D,tmp[N],rt,tot;
int X;
LL minx[N],ad[N],miad[N],val[N];

bool cmp(int x,int y){return a[x][D]<a[y][D];}
void pushup(int i)
{
	mx[i][0]=max(max(mx[lc][0],mx[rc][0]),a[i][0]);
	mx[i][1]=max(max(mx[lc][1],mx[rc][1]),a[i][1]);
	mi[i][0]=min(min(mi[lc][0],mi[rc][0]),a[i][0]);
	mi[i][1]=min(min(mi[lc][1],mi[rc][1]),a[i][1]);
}
void cal(int i,LL x,LL y)//x:miad  y: ad
{
	miad[i]=min(miad[i],ad[i]+x);
	minx[i]=min(minx[i],val[i]+x);
	ad[i]+=y;val[i]+=y;
}
void pushdown(int i)
{
	if(miad[i]||ad[i]){
		if(lc)cal(lc,miad[i],ad[i]);
		if(rc)cal(rc,miad[i],ad[i]);
		miad[i]=0;ad[i]=0;
	}
}
void build(int &i,int l,int r,int d)
{
	int mid=(l+r)>>1;D=d;
	nth_element(tmp+l,tmp+mid,tmp+r+1,cmp);
	i=tmp[mid];lc=rc=0;
	if(l<mid)build(lc,l,mid-1,d^1);
	if(r>mid)build(rc,mid+1,r,d^1);
	pushup(i);if(lc)fa[lc]=i;if(rc)fa[rc]=i;
}
void insert(int i,LL k)
{
	if(mi[i][0]>X||mx[i][1]<X)
		return;
	if(mx[i][0]<=X&&mi[i][1]>=X){
		cal(i,min(0ll,k),k);
		return;
	}
	pushdown(i);
	if(a[i][0]<=X&&a[i][1]>=X){
		minx[i]=min(minx[i],val[i]+min(0ll,k));
		val[i]+=k;
	}
	if(lc)insert(lc,k);
	if(rc)insert(rc,k);
}
void pdpath(int i){if(i!=rt)pdpath(fa[i]);pushdown(i);}
LL A[N],sum[N];
struct node{
	int op,x,y,id;
}q[N];
int main()
{
	mi[0][0]=mi[0][1]=0x3f3f3f3f;
	mx[0][0]=mx[0][1]=0;
	int n,m,i;
	n=gi();m=gi();
	for(i=1;i<=n;i++){
		A[i]=gi();
		sum[i]=sum[i-1]+A[i];
	}
	for(i=1;i<=m;i++){
		q[i].op=gi();
		q[i].x=gi();q[i].y=gi();
		if(q[i].op==2){
			tot++;
			tmp[tot]=tot;
			a[tot][0]=q[i].x;a[tot][1]=q[i].y;
			val[tot]=minx[tot]=sum[q[i].y]-sum[q[i].x-1];
			q[i].id=tot;
		}
	}
	build(rt,1,tot,0);
	for(i=1;i<=m;i++){
		if(q[i].op==1){
			X=q[i].x;
			insert(rt,q[i].y-A[q[i].x]);
			A[q[i].x]=q[i].y;
		}
		else{
			pdpath(q[i].id);
			printf("%lld\n",minx[q[i].id]);
		}
	}
}

 

20200525B

題解:

當點Ti爲1時,點S_{p+i}要滿足0<=a(p+i)+b<c,才能使答案不匹配

我們可以把括號打開,得:-ai<=ap+b<c-ai

發現我們的查詢只與p有關,那麼我們就可以把位置i看作對-ai到ai的一個區間覆蓋1

這個可以動態開點線段樹直接維護O(mlogn)

代碼:(之前一直TLE,是因爲線段樹query裏面沒有寫區間不相交的判斷)

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int gi()
{
	char c;int num=0,flg=1;
	while((c=getchar())<'0'||c>'9')if(c=='-')flg=-1;
	while(c>='0'&&c<='9'){num=num*10+c-48;c=getchar();}
	return num*flg;
}
#define N 100005
struct node{
	int l,r,x;
}a[N<<8];
int rt,tot;
void insert(int &i,int l,int r,int x,int k)
{
	if(!i)i=++tot;
	a[i].x+=k;
	if(l==r)return;
	int mid=(l+r)>>1;
	if(x<=mid)insert(a[i].l,l,mid,x,k);
	else insert(a[i].r,mid+1,r,x,k);
}
int query(int i,int l,int r,int ql,int qr)
{
	if(!i||ql>r||qr<l)return 0;
	if(ql<=l&&r<=qr)return a[i].x;
	int mid=(l+r)>>1;
	return query(a[i].l,l,mid,ql,qr)+query(a[i].r,mid+1,r,ql,qr);
}
int T[N],L[N],R[N];
int main()
{
	int n,k,b,c,m,Q,i,x,l,r,op;
	n=gi();k=gi();b=gi();c=gi();m=gi();
	for(i=0;i<m;i++){
		scanf("%1d",&T[i]);
		l=(1ll*c-1ll*b-1ll*k*i)%n;
		r=(1ll*n-1ll*b-1ll*k*i)%n;
		if(l<0)l+=n;if(r<0)r+=n;
		L[i]=l;R[i]=r;
		
		l=L[i];r=R[i];
		if(T[i])swap(l,r);
		if(l<=r){
			insert(rt,0,n-1,l,1);
			insert(rt,0,n-1,r,-1);
		}
		else{
			insert(rt,0,n-1,0,1);
			insert(rt,0,n-1,r,-1);
			insert(rt,0,n-1,l,1);
		}
	}
	Q=gi();
	while(Q--){
		op=gi();x=gi();
		if(op==1){
			x=1ll*k*x%n;
			printf("%d\n",query(rt,0,n-1,0,x));
		}
		else{
			l=L[x];r=R[x];
			if(T[x])swap(l,r);
			if(l<=r){
				insert(rt,0,n-1,l,-1);
				insert(rt,0,n-1,r,1);
			}
			else{
				insert(rt,0,n-1,0,-1);
				insert(rt,0,n-1,r,1);
				insert(rt,0,n-1,l,-1);
			}
			T[x]^=1;
			l=L[x];r=R[x];
			if(T[x])swap(l,r);
			if(l<=r){
				insert(rt,0,n-1,l,1);
				insert(rt,0,n-1,r,-1);
			}
			else{
				insert(rt,0,n-1,0,1);
				insert(rt,0,n-1,r,-1);
				insert(rt,0,n-1,l,1);
			}
		}
	}
}

 

 

20200525C

 

題解:

它的式子其實是

val[i][0]=i/n*val[i-1][0]+(n-i-1)/n*val[i+1][0]+1/n*(val[i+1][1]+1)

表示:選中一個權值爲1的點翻轉後的期望+選中一個除自身以外的0點翻轉後的期望+翻轉自己後的期望(貢獻一步)

下面的反之亦然

解二元一次方程,我們可以維護兩個未知數的係數與一個常數的三元組

有很多邊界需要特盤

代碼:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100005
int fir[N],to[2*N],nxt[2*N],cnt;
void adde(int a,int b)
{
	to[++cnt]=b;nxt[cnt]=fir[a];fir[a]=cnt;
	to[++cnt]=a;nxt[cnt]=fir[b];fir[b]=cnt;
}
const int mod=1000000007;
int n,a[N],dis[N],siz[N];
void dfs1(int u,int ff)
{
	siz[u]=1;
	for(int v,p=fir[u];p;p=nxt[p]){
		if((v=to[p])!=ff){
			dfs1(v,u);
			dis[u]=(1ll*dis[u]+dis[v]+siz[v])%mod;
			siz[u]+=siz[v];
		}
	}
}
void dfs2(int u,int ff)
{
	for(int v,p=fir[u];p;p=nxt[p]){
		if((v=to[p])!=ff){
			dis[v]=((1ll*dis[v]+dis[u]-dis[v]-siz[v]+n-siz[v])%mod+mod)%mod;
			dfs2(v,u);
		}
	}
}
int F[2],G[2],tong[2],inv[N];
struct node{
	int a,b,c;
	node(){a=b=c=0;}
	node(int x,int y,int z){a=x;b=y;c=z;}
	node operator + (const node &t)const{return node((a+t.a)%mod,(b+t.b)%mod,(c+t.c)%mod);}
	node operator - (const node &t)const{return node((a+mod-t.a)%mod,(b+mod-t.b)%mod,(c+mod-t.c)%mod);}
	node operator * (const int &t)const{return node(1ll*a*t%mod,1ll*b*t%mod,1ll*c*t%mod);}
	int val(){return (1ll*a*F[0]+1ll*b*F[1]+1ll*c)%mod;}
}f[N][2],P,Q;
int ksm(int x,int y)
{
	int ret=1;
	while(y){
		if(y&1)ret=1ll*ret*x%mod;
		y>>=1;x=1ll*x*x%mod;
	}
	return ret;
}
int main()
{
	int i,x,sum=0,ans=0;
	scanf("%d",&n);
	for(i=1;i<=n;i++){scanf("%1d",&a[i]);tong[a[i]]++;}
	for(i=2;i<=n;i++){scanf("%d",&x);adde(i,x);}
	if(n==2){
		if(tong[0]==2||tong[1]==2)printf("0\n");
		else printf("500000004\n");
		return 0;
	}
	dfs1(1,0);dfs2(1,0);
	f[1][0]=node(1,0,0);f[1][1]=node(0,1,0);
	inv[0]=inv[1]=1;
	for(i=2;i<=n;i++)inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
	for(i=1;i<n-1;i++){
		f[i+1][0]=(f[i][0]*n-f[i-1][0]*(i-1)-f[i-1][1]-node(0,0,i!=1))*inv[n-i];
		f[i+1][1]=(f[i][1]*n-f[i-1][1]*i-f[i+1][0]-node(0,0,1))*inv[n-i-1];
	}
	P=(f[n-2][0]*(n-2)+f[n-2][1]+node(0,0,1))*inv[n]-f[n-1][0];
	Q=f[n-2][1]*(1ll*(n-1)*inv[n]%mod)-f[n-1][1];
	if(!P.b)swap(P,Q);
	P=P-Q*(1ll*P.a*ksm(Q.a,mod-2)%mod);
	F[1]=-1ll*P.c*ksm(P.b,mod-2)%mod;
	F[0]=-1ll*(Q.c+1ll*Q.b*F[1])%mod*ksm(Q.a,mod-2)%mod;
	G[0]=f[tong[0]][0].val();G[1]=f[tong[0]][1].val();
	for(i=1;i<=n;i++){
		ans=(1ll*ans+1ll*G[a[i]]*dis[i])%mod;
		sum=(sum+dis[i])%mod;
	}
	printf("%d\n",(1ll*ans+1ll*sum*inv[n])%mod*inv[n]%mod);
}

 

 

 

 

20200526a

 

題解:n^2枚舉*n^2簡單DP

應該是可以優化成n^2預處理+n^2枚舉的

代碼:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int gi()
{
	char c;int num=0,flg=1;
	while((c=getchar())<'0'||c>'9')if(c=='-')flg=-1;
	while(c>='0'&&c<='9'){num=num*10+c-48;c=getchar();}
	return num*flg;
}
#define N 55
#define LL long long
LL f[N][N],sum1[N][N],sum2[N][N],mx1[N][N],mx2[N][N];
int a[N][N];
int main()
{
	int T,n,K,i,j,k,l;
	T=gi();
	while(T--){
		n=gi();K=gi();n--;
		memset(f,0,sizeof(f));
		memset(a,0,sizeof(a));
		for(i=1;i<=n;i++)
			for(j=0;j<=i;j++)
				a[i-j][j]=gi();
		if(K==2){
			for(i=1;i<=n;i++){
				for(j=1;j<=n;j++){
					sum1[i][j]=sum1[i][j-1]+a[i][j];
					sum2[i][j]=sum2[i-1][j]+a[i][j];
					mx1[i][j]=max(mx1[i][j-1],sum1[i][j]);
					mx2[i][j]=max(mx2[i-1][j],sum2[i][j]);
				}
			}
		}
		LL ans=0,s1=0,s2,ret;
		for(i=0;i<=n;i++){
			s1+=a[i][0];s2=0;
			for(j=0;j<=n;j++){
				s2+=a[0][j];ret=0;
				if(K==2){
					for(k=0;k<=i;k++){
						for(l=0;l<=j;l++){
							if(k==0&&l==0)continue;
							f[k][l]=max(f[k][l-1]+(k==i?mx2[n][l]:mx2[k][l]),f[k-1][l]+(l==j?mx1[k][n]:mx1[k][l]));
							ret=max(ret,f[k][l]);
						}
					}
				}
				ans=max(ans,s1+s2+ret);
			}
		}
		printf("%lld\n",ans);
	}
}

 

 

 

 

20200526b

 

題解:

先枚舉把水全部聚集到一個地方[l,r]

顯然把l以左的水全部聚集過來的代價至少爲Σa[i]-mil[i](mil表示前綴最小值)

右邊也是一樣的

聚集過來了之後可以二分一下當前水面高度,把[l,r]中高出來的土整體向下鏟

由於當右端點向右走一格,水面是不會上升的,所以我們可以利用這個單調性,先算出整數的水面高度(相當於估一個範圍)

然後再精確計算實際的水面高度

代碼:(之前前綴min值取錯了,竟然水過了)

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 5005
int T,n;
int a[N],w[N],cnt[1005],sum[N];
int sul[N],sur[N],mil[N],mir[N];
int main()
{
	int i,j,sumw;
	scanf("%d",&T);
	while(T--){
		sumw=0;
		scanf("%d",&n);a[0]=a[n+1]=10000000;
		for(i=1;i<=n;i++)scanf("%d",&a[i]),sum[i]=sum[i-1]+a[i];
		for(i=1;i<=n;i++)scanf("%d",&w[i]),sumw+=w[i];
		memset(sul,0,sizeof(sul));memset(sur,0,sizeof(sur));
		memset(mil,0,sizeof(mil));memset(mir,0,sizeof(mir));
		int lp=0,rp=0;
		for(i=1;i<=n;i++){
			if(w[i]){
				lp=i;mil[i]=a[i];
				for(j=i+1;j<=n;j++)mil[j]=min(a[j],mil[j-1]);
				for(j=i+1;j<=n;j++)sul[j]=sul[j-1]+a[j]-mil[j];
				break;
			}
		}
		for(i=n;i>=1;i--){
			if(w[i]){
				rp=i;mir[i]=a[i];
				for(j=i-1;j>=1;j--)mir[j]=min(a[j],mir[j+1]);
				for(j=i-1;j>=1;j--)sur[j]=sur[j+1]+a[j]-mir[j];
				break;
			}
		}
		int len,h,sumd;
		double ans=1e9;
		for(i=1;i<=n;i++){
			memset(cnt,0,sizeof(cnt));
			len=0;h=1000;sumd=0;
			for(j=i;j<=n;j++){
				if(a[j]<=h){
					sumd+=h-a[j];
					cnt[a[j]]++;
					len++;//len means the number of underwater stones
					while(sumd>sumw){// some stone will come out
						len-=cnt[h];
						sumd-=len;
						h--;
					}
				}
				double x=1.0*h+1.0*(sumw-sumd)/len;
				double ret=(sum[j]-sum[i-1])-((j-i+1)*x-sumw);
				int lh=a[i-1],rh=a[j+1];
				if(lp<=i-1)lh=mil[i-1],ret+=sul[i-1];
				if(j+1<=rp)rh=mir[j+1],ret+=sur[j+1];
				if(x>min(lh,rh))ret+=(j-i+1)*(x-min(lh,rh));
				ans=min(ans,ret);
			}
		}
		printf("%.5f\n",ans);
	}
}

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章