9.24 csp(没学会的网络流)

T1、商品

因为边界 l , r 是线性移动的,所以答案可以线性改变,直接用set维护连续段(小于l的和大于r的)的个数,并维护ans即可。

因为set的一个小错误调了两个小时,代码打成了一坨,结果最后改完了但是没交上。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define int ll
typedef pair<int,int> pii;
#define fi first
#define se second
#define ps emplace_back
#define mk make_pair
const int N=1e6+10;
inline ll read(){
	char c=getchar();ll x=0,f=1;
	while(!isdigit(c))(c=='-'?f=-1:f=1),c=getchar();
	while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return x*f;
}
int n,d,a[N],b[N];
vector<int> v[N];
struct jj{
	mutable int l,r;
	inline bool operator <(const jj&x)const{return l<x.l;}
};
set<jj>s,s1;
inline void ins(int pos){
	auto it=s.insert({pos,pos}).fi,man=it;
	if((++man)!=s.end()){
		++it;
		if(it->l==pos+1){
			// ans-=a[pos]-max(la,a[pos+1]);
			it->l=pos;
			auto i=it;
			s.erase(--i);
		}
		else --it;
		// else ans-=a[pos+1]-a[pos];
	}
	if(it!=s.begin()){
		int r=it->r;
		--it;
		if(it->r==pos-1){
			// ans-=a[pos]-max(la,a[pos-1]);
			it->r=r;
			s.erase(++it);
		}
		// else ans-=a[pos-1]-a[pos];
	}
}
inline void del(int pos){
	auto it=s1.lower_bound({pos,pos});
	if(it==s1.end()||it->l>pos)--it;
	if(it->l!=pos){
		// ans-=min(la,a[pos-1])-a[pos];
		int l=it->l;
		it->l=pos,s1.insert({l,pos-1});
	}
	if(it->r!=pos){
		// ans-=min(la,a[pos+1])-a[pos];
		int r=it->r;
		it->r=pos;s1.insert({pos+1,r});
	}
	s1.erase({pos,pos});
}
ll ans=0,anss=0;
main(){
	#ifndef ONLINE_JUDGE
	freopen("goods.in","r",stdin);
	freopen("goods.out","w",stdout);
	#endif
	//ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	n=read(),d=read();
	for(int i=1;i<=n;++i){
		b[i]=a[i]=read();
	}
	// for(int i=1;i<n;++i)
	// 	ans+=abs(a[i]-a[i+1]);
	sort(b+1,b+1+n);
	int n1=unique(b+1,b+1+n)-b-1;
	// cout<<b[2]<<endl;
	for(int i=1;i<=n;++i){
		int pos=lower_bound(b+1,b+1+n1,a[i])-b;
		v[pos].ps(i);
	}
	s1.insert({1,n});
	b[0]=b[1];
	for(int i=1,k=1,l,r;i<=n1;++i){
		l=b[i],r=l+d;
		ans-=2ll*s.size()*(b[i]-b[i-1]);
		if(s.size()){
			auto it=s.begin();
			if(it->l==1ll)ans+=b[i]-b[i-1];
			auto itt=s.rbegin();
			if(itt->r==n)ans+=b[i]-b[i-1];
		}
		for(auto j:v[i])ins(j);
		while(k<=n1&&b[k]<=r){
			ans+=2ll*s1.size()*(b[k]-b[k-1]);
			if(s1.size()){
				auto it=s1.begin();
				if(it->l==1)ans-=b[k]-b[k-1];
				auto itt=s1.rbegin();
				if(itt->r==n)ans-=b[k]-b[k-1];
			}
			for(auto j:v[k]){
				del(j);
			}
			++k;
		}
		if(k>n1){
			anss=max(ans,anss);break;
		}
		ll ko=ans;
		ko+=2ll*s1.size()*(r-b[k-1]);
		if(s1.size()){
			auto it=s1.begin();
			if(it->l==1)ko-=r-b[k-1];
			auto itt=s1.rbegin();
			if(itt->r==n)ko-=r-b[k-1];
		}
		anss=max({ans,ko,anss});
	}
	s.clear(),s1.clear();
	s1.insert({1,n});
	b[n1+1]=b[n1];
	ans=0;
	for(int i=n1,l,r,k=n1;i;--i){
		r=b[i],l=r-d;
		ans-=2ll*s.size()*(b[i+1]-b[i]);
		if(s.size()){
			auto it=s.begin();
			if(it->l==1ll)ans+=b[i+1]-b[i];
			auto itt=s.rbegin();
			if(itt->r==n)ans+=b[i+1]-b[i];
		}
		for(auto j:v[i])ins(j);
		while(k&&b[k]>=l){
			ans+=2ll*s1.size()*(b[k+1]-b[k]);
			if(s1.size()){
				auto it=s1.begin();
				if(it->l==1)ans-=b[k+1]-b[k];
				auto itt=s1.rbegin();
				if(itt->r==n)ans-=b[k+1]-b[k];
			}
			for(auto j:v[k])del(j);
			--k;
		}
		if(k<=0){
			anss=max(ans,anss);break;
		}
		ll ko=ans;
		ko+=2ll*s1.size()*(b[k+1]-l);
		if(s1.size()){
			auto it=s1.begin();
			if(it->l==1)ko-=b[k+1]-l;
			auto itt=s1.rbegin();
			if(itt->r==n)ko-=b[k+1]-l;
		}
		anss=max(anss,ko);
	}
	cout<<anss;
}

T2、价值

\[\Huge 学会读题 \]

首先第一句话可以保证每两颗相邻的树之间的标号是连续的,所以对于叶子节点来说只需要关注最小的和最大的。

那么dp数组只记相关节点的状态即可。f[i][0/1][0/1][0/1]表示对于以i点为根节点的子树内i、最小的叶子节点、最大的叶子节点选没选就可以转移了。

然后就是大力分讨,但分了一个下午也没分出来,最后发现直接递推无需分讨。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define fi first
#define se second
#define ps emplace_back
#define mk make_pair
const int N=1e5+10;
const ll mod=998244353;
inline ll read(){
	char c=getchar();ll x=0,f=1;
	while(!isdigit(c))(c=='-'?f=-1:f=1),c=getchar();
	while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return x*f;
}
ll f[100005][2][2][2],n,xiao[N],da[N];
vector<int> son[N];
ll man[2][2][2];
int main(){
	#ifndef ONLINE_JUDGE
	freopen("value.in","r",stdin);
	freopen("value.out","w",stdout);
	#endif
	//ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	n=read();
	for(int i=2;i<=n;++i){
		son[read()].ps(i);
	}
	for(int i=n;i;--i){
		if(!son[i].size())
			xiao[i]=da[i]=i;
		else {
			xiao[i]=n+1;
			for(auto j:son[i])
				xiao[i]=min(xiao[i],xiao[j]),da[i]=max(da[i],da[j]);
		}
	}
	for(int i=n;i;--i){
		if(!son[i].size())f[i][0][0][0]=1;
		else{
			int j=son[i][0];
			for(int l1=0;l1<2;++l1)
				for(int l2=0;l2<2;++l2){
					f[i][0][l1][l2]=(f[j][0][l1][l2]+f[j][1][l1][l2])%mod;
					if(j!=xiao[i])f[i][1][l1][l2]=f[j][0][l1][l2];
				}
			if(j==da[j])(f[i][1][1][1]+=f[j][0][0][0])%=mod;
			for(int k=1;k<son[i].size();++k){
				int j=son[i][k];
				memcpy(man,f[i],sizeof(man));
				f[i][0][0][0]=f[i][0][0][1]=f[i][0][1][0]=f[i][0][1][1]=f[i][1][0][0]=f[i][1][0][1]=f[i][1][1][0]=f[i][1][1][1]=0;
				bool f1=(k==1&&xiao[son[i][0]]==da[son[i][0]]),f2=(xiao[j]==da[j]),f3=(j==da[j]);
				for(int l1=0;l1<2;++l1){
					for(int l2=0;l2<2;++l2){
						for(int l3=0;l3<2;++l3){
							for(int r1=0;r1<2;++r1){
								for(int r2=0;r2<2;++r2){
									for(int r3=0;r3<2;++r3){
										int i1,i2,i3;
										//0 0
										i1=l1,i2=l2,i3=r3;
										(f[i][i1][i2][i3]+=(man[l1][l2][l3]*f[j][r1][r2][r3])%mod)%=mod;
										//0 1
										if(!l3&&!r2){
											i1=l1,i2=l2|f1,i3=r3|f2;
											(f[i][i1][i2][i3]+=(man[l1][l2][l3]*f[j][r1][r2][r3]%mod))%=mod;
										}
										//1 0
										if(!l1&&!r1){
											i1=1,i2=l2,i3=r3|f3;
											(f[i][i1][i2][i3]+=(man[l1][l2][l3]*f[j][r1][r2][r3]%mod))%=mod;
										}
										//1 1
										if(!l1&&!r1&&!l3&&!r2&&!f3){
											i1=1,i2=l2|f1,i3=r3|f2|f3;
											(f[i][i1][i2][i3]+=(man[l1][l2][l3]*f[j][r1][r2][r3]%mod))%=mod;
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
	ll ans=0;
	for(int i=0;i<2;++i)
		for(int j=0;j<2;++j)
			for(int k=0;k<2;++k)
				ans+=f[1][i][j][k];
	if(da[1]!=xiao[1])ans+=f[1][0][0][0]+f[1][1][0][0];
	cout<<ans%mod;

}

T3、货币

题解说是网络流的切糕模型板子,没学呢,先挂个标记。

T4、资本

生成函数。(我要是把网络流和多项式弄懂了就学这个)

[========]

[========]

今天也被薄纱了,开题策略确实有问题,可能看题不够深吧,patience。

posted @ 2024-09-24 21:45  lzrG23  阅读(39)  评论(0编辑  收藏  举报