首页 > 其他分享 >9.24 csp(没学会的网络流)

9.24 csp(没学会的网络流)

时间:2024-09-24 21:48:38浏览次数:1  
标签:9.24 int auto 学会 pos ans itt csp s1

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。

标签:9.24,int,auto,学会,pos,ans,itt,csp,s1
From: https://www.cnblogs.com/GGrun-sum/p/18430110

相关文章

  • 9.24 开发MES系统日志二
    今天通过大模型设计了MES系统的数据库表,我感觉它其中需要改的地方应该会很多,本次使用大模型来回答这个问题只是为了有个示例,让心里有底,比如在我看来最基本的存储各种二维码的字段不存在,这一点需要仔细补充。同时三天之内需要提出一个队本系统的问题,其实我早就想好了想要提交的问......
  • 9.24学习
    转载,非原创,写在这记录用的聊一聊我最近使用的uniCloud是个什么玩意?-腾讯云开发者社区-腾讯云(tencent.com)什么是uniClouduniCloud是DCloud联合阿里云、腾讯云,为开发者提供的基于serverless模式和js编程的云开发平台。到底是怎么一回事?听我给你简单说一下对架构演......
  • 2024CSP-S提高组初赛试题及解析( 第一部分选择题(1-5))
    ......
  • 2024CSP-S提高组初赛试题及解析( 第一部分选择题(6-10))
    ......
  • 2024CSP-S提高组初赛试题及解析( 第一部分选择题(10-15))
    ......
  • 2023CSP-J 普及组第二轮试题及解析( 第三题一元二次方程)
    参考程序代码:#include<bits/stdc++.h>usingnamespacestd;intt,m,a,b,c;intaa,bb,gd1,gd2;intgcd(inta,intb){ if(a%b==0)returnb; returngcd(b,a%b);}intmain(){ scanf("%d%d",&t,&m); while(t--) { scanf("%d%d%d"......
  • 2024.9.24-课后试验问题整理
    1、java中字符和字符串用equals()方法进行判断是否相等。""比较的是地址publicclassEnumTest{publicstaticvoidmain(String[]args){Sizes=Size.SMALL;Sizet=Size.LARGE;//s和t引用对象是否为同一个?System.out.println(st);//是原始数据吗?System.out.println(s.get......
  • 2024.9.24- java开学测
    1、定义student类,其中包括五个私有变量(stunumber,name,age,sex,score)。各成员的含义如下:变量stunumber为字符串类型String,用于存储学生的学号(有8位数字组成)。变量name为字符串类型String,用于存储学生的姓名。变量age为int类型,用于存储学生的年龄。变量sex为boolean类型,用于存储学......
  • 2024.9.24 思维导图与PDF
    哈哈哈终于有我也用过的东西啦~Xmind一款打工人用了都说好的软件(#.#)【知识小课堂1】不同款式的思维导图:【知识小课堂2】PDF转换器!1、PDF(便携式文档格式),这种文件格式与操作系统平台无关——PDF文件不管是在Windows还是别的操作系统中都是通用的。2、这一特点使它成为在I......
  • 设计模式之中介模式(三分钟学会一个设计模式)
    中介模式(Mediator)又称之为调停模式。mediator[ˈmiːdieɪtə(r)]n.调停者;斡旋者;解决纷争的人(或机构);本意就是解决纠纷的中间人它是面向对象六大原则中最少知道原则的一个典型应用。(关于面向对象六大原则,可看前文:https://www.cnblogs.com/jilodream/p/5353512.html)大概意......