题面传送门

离谱题,结论出奇的简单。

首先我们考虑\(O(nq)\)怎么做。

显然所有C都要放在最终序列中,然后问题就变成往里面填T

我们考虑第一个T填在能填的最开始的位置上,因为如果这个T往后移动,那么其实只会更劣。因此一个基础的想法就是能填就填。

我们发现这个形式和最大子段和满足的性质是一样的,即一个最大子段和是满足这个性质的。

而对应的,一个区间的最大子段和去掉以后,前区间的后缀和后区间的前缀都是非正的。

而考虑现在将这两个区间删掉若干个T使得这两个区间的总和恰好为\(0\),容易发现这是必要的,为了最优,我们应该使左区间删掉右边的,右区间删掉左边的。这样左区间的前缀和右区间的后缀本身就是非负的,而左区间的后缀和右区间的前缀也被删成了非负的。

所以答案就是最大子段和减去区间和,用线段树维护,时间复杂度\(O(n+q\log n)\)

code:

#include<bits/stdc++.h>
#define Gc() getchar() 
#define Me(x,y) memset(x,y,sizeof(x))
#define Mc(x,y) memcpy(x,y,sizeof(x))
#define d(x,y) ((m)*(x-1)+(y))
#define R(n) (rnd()%(n))
#define Pc(x) putchar(x)
#define LB lower_bound
#define UB upper_bound
#define PB push_back
using ll=long long;using db=double;using lb=long db;using ui=unsigned;using ull=unsigned ll;
using namespace std;const int N=600+5,M=2e7,K=(1<<10)+5,mod=1e9+7,Mod=mod-1;ll INF=1e18+7;const db eps=1e-5;mt19937 rnd(time(0));
int n,m,k,x,y,Q[N],P[N];ll f[N][N],g[N],Ans;
int main(){
	freopen("1.in","r",stdin);
	int i,j,h;scanf("%d%d",&n,&k);m=2*n;for(i=1;i<=k;i++) scanf("%d%d",&x,&y),P[x]=y,P[y]=x,Q[x]=Q[y]=1;
	for(i=1;i<=m;i++) Q[i]=Q[i-1]+(!Q[i]);for(g[0]=1,i=2;i<=m;i+=2) g[i]=g[i-2]*(i-1)%mod;
	for(i=m;i;i--){
		for(j=i;j<=m;j++) {
			int Fl=0;if((Q[j]-Q[i-1])&1) continue;for(h=i;h<=j;h++) if(Q[h]==Q[h-1]&&(P[h]<i||P[h]>j)) {Fl=1;break;}if(Fl) continue;
			f[i][j]=g[Q[j]-Q[i-1]];for(h=i+1;h<=j;h++) f[i][j]=(f[i][j]+(mod-g[Q[h-1]-Q[i-1]])*f[h][j])%mod;Ans+=f[i][j]*g[m-2*k-(Q[j]-Q[i-1])]%mod;
		}
	}printf("%lld\n",Ans%mod);
}

原文地址:http://www.cnblogs.com/275307894a/p/16886427.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性