QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#717755#9252. Penguins in RefrigeratorHkueenWA 0ms20120kbC++143.7kb2024-11-06 18:53:132024-11-06 18:53:16

Judging History

你现在查看的是最新测评结果

  • [2024-11-06 18:53:16]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:20120kb
  • [2024-11-06 18:53:13]
  • 提交

answer

/*
这种题
我当然是不会做的

哇,这个思路可以啊
考虑把这n个元素分到两个集合S,T中,其中S={i|w[i]<=W/2},T={i|w[i]>W/2}
那么S中的元素互相可以随便交换,T中的元素相对顺序则无法改变
我们可以对每个S中的元素i求出一个L[i]和一个R[i],分别表示i左右第一个满足w[i]+w[j]>W的j(显然j∈T)
稍微想想可以发现,每对[L,R]要么包含,要么不交,因此形成一个树形结构
拟造一个初始序列,里面只包含所有T中的元素
那么我们对于每棵树,从底到根地插入i,当插入i时,算出(L[i],R[i]])现在已经插入了多少个元素(在T中的也算),i可以在任选一个位置插进去
所以这里对方案数的贡献是乘上 元素个数+1
这样可以算出第一问

第二问非常简单,对于每个T中的元素,按照原顺序连边(T[i],T[i+1])
对于每个S中的元素,连边(L[i],i),(i,R[i])
跑最小拓扑序即可

我靠要离散化
6,没看到
*/
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int re(){
	int x=0,c=getchar();
	while(c<48||c>57)c=getchar();
	while(c>47&&c<58)x=(x<<3)+(x<<1)+(c&15),c=getchar();
	return x;
}
void wr(int x){
	if(x>9)wr(x/10);
	putchar(x%10|48);
}
constexpr int mod=1e9+7,N=5e6+10;
int tr[N],W,fl,n,tot;
int lowbit(int x){return x&-x;}
void ad(int x,int v){
	if(fl<2)x=tot-x+1;
	//fprintf(stderr,"ad(%d,%d)\n",x,v);
	if(!fl)for(int i=x;i<=tot;i+=lowbit(i))tr[i]=max(tr[i],v);
	else if(fl==1)for(int i=x;i<=tot;i+=lowbit(i))tr[i]=min(tr[i],v);
	else for(int i=x;i<=n;i+=lowbit(i))tr[i]+=v;
}
int su(int x){
	if(fl<2)x=tot-x+1;
	//fprintf(stderr,"su(%d)\n",x);
	int res;
	if(!fl){
		res=0;
		for(int i=x;i;i-=lowbit(i))res=max(res,tr[i]);
	}
	else if(fl==1){
		res=n+1;
		for(int i=x;i;i-=lowbit(i))res=min(res,tr[i]);
	}
	else{
		res=0;
		for(int i=x;i;i-=lowbit(i))res+=tr[i];
	}
	return res;
}
ll ans;
int i,p[N],w[N],las;
bool ins[N];
int first[N],cnt;
struct Edge{
	int u,v,nex;
}a[N<<1];
int d[N];
void add(int u,int v){
	//printf("%d %d\n",u,v);
	a[++cnt]={u,v,first[u]};
	first[u]=cnt;
	++d[v];
}
int L[N],R[N],qzh[N],tmp[N];
priority_queue<pair<int,int> >q;
int ls(int x){return lower_bound(tmp+1,tmp+1+tot,x)-tmp;}
int main(){
	n=re(),W=re();
	for(i=1;i<=n;++i)p[i]=re();
	for(i=1;i<=n;++i)tmp[i]=re();
	for(i=1;i<=n;++i)w[i]=tmp[p[i]];
	//for(i=1;i<=n;++i)printf("%d ",p[i]);putchar(10);
	//for(i=1;i<=n;++i)printf("%d ",w[i]);putchar(10);
	for(i=1;i<=n;++i){
		qzh[i]=qzh[i-1]+1;
		if(w[i]<=(W>>1))ins[i]=1,--qzh[i];
		else if(las)add(las,i),las=i;
		else las=i;
		tmp[++tot]=w[i],tmp[++tot]=W-w[i]+1;
	}
	sort(tmp+1,tmp+tot+1);
	tot=unique(tmp+1,tmp+tot+1)-tmp-1;
	for(i=1;i<=n;++i){
		if(ins[i]){
			L[i]=su(ls(W-w[i]+1));
			if(L[i])add(L[i],i);
		}
		else ad(ls(w[i]),i);
	}
	for(i=fl=1;i<=tot;++i)tr[i]=n+1;
	for(i=n;i;--i){
		if(ins[i]){
			R[i]=su(ls(W-w[i]+1));
			if(R[i]<=n)add(i,R[i]);
		}
		else ad(ls(w[i]),i);
	}
	//for(i=1;i<=n;++i)printf("L[%d]=%d R[%d]=%d\n",i,L[i],i,R[i]);
	//return 0;
	fl=2;
	for(i=1;i<=tot;++i)tr[i]=0;
	for(i=1;i<=n;++i)if(ins[i])q.push({-(R[i]-L[i]),i});
	ans=1;
	while(!q.empty()){
		int u=q.top().second;q.pop();
		ad(L[u]+1,1);
		ans=ans*(qzh[R[u]-1]-qzh[L[u]]+su(R[u]-1)-su(L[u]))%mod;
		//printf("%lld ",ans);
		//printf("u=%d %d %d ans*=(%d-%d+%d-%d)\n",u,L[u],R[u]-1,qzh[R[u]-1],qzh[L[u]],su(R[u]-1),su(L[u]));
	}
	printf("%lld\n",ans);
	for(i=1;i<=n;++i)if(!d[i])q.push({-p[i],i});
	while(!q.empty()){
		wr(-q.top().first),putchar(32);
		int u=q.top().second;q.pop();
		for(int i=first[u];i;i=a[i].nex){
			int v=a[i].v;
			if(!--d[v])q.push({-p[v],v});
		}
	}
	return 0;
}

詳細信息

Test #1:

score: 0
Wrong Answer
time: 0ms
memory: 20120kb

input:

5 10
1 2 3 4 5
6 5 3 9 2

output:

3
1 2 3 4 5 

result:

wrong answer 2nd lines differ - expected: '5 4 2 1 3', found: '1 2 3 4 5 '