代码源div1

103 子串最大差

题目描述

在这里插入图片描述

题解

每个区间会有一个最大值和最小值,最大差是最大值减最小值。我们需要将所有的子串的最大差累加起来。将问题转化一下,可以单独计算每个a[i]作为最大值的贡献以及最小值的贡献。而a[i]作为最大值的贡献就是包含它的所有满足它是最大值的字串。注意到,从a[i]向左一直走,找到能维持a[i]是最大值的最左端,向右一直走,找到能维持a[i]最大值的最右端,那么满足条件的子串数就是左边的长度乘右边的长度。这个东西可以通过二分+ST表实现,ST表 NlogN预处理以后,查询O(1)。整体复杂度就是NlogN。或者直接写一个线段树二分也可以。但所求的东西可以很方便的用单调栈维护。易错点是,如果两遍单调栈维护的都是非严格单调序列,那么一个子串可能会被重复计数,比如3 2 2 3这个子串会被两个3分别计算一次。因此需要一遍是非严格,一遍是严格。

代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=5e5+10;
int n,a[N],lef[N],rig[N];
int s[N],top;
ll ans; 
int main(){
//	freopen("1.in","r",stdin);
//	freopen("2.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<=n;i++){
		while(top&&a[s[top]]<=a[i]) top--;
		lef[i]=i-s[top];
		s[++top]=i;	
	}
	top=0;s[0]=n+1;
	for(int i=n;i;i--){
		while(top&&a[s[top]]<a[i]) top--;
		rig[i]=s[top]-i;
		s[++top]=i;
	}
	for(int i=1;i<=n;i++){
		//cout<<lef[i]<<' '<<rig[i]<<endl;
		ans+=1LL*a[i]*lef[i]*rig[i];
	}
	top=0;s[0]=0;
	for(int i=1;i<=n;i++){
		while(top&&a[s[top]]>=a[i]) top--;
		lef[i]=i-s[top];
		s[++top]=i;
	}
	top=0;s[0]=n+1;
	for(int i=n;i;i--){
		while(top&&a[s[top]]>a[i]) top--;
		rig[i]=s[top]-i;
		s[++top]=i;
	}
	for(int i=1;i<=n;i++){
		ans-=1LL*a[i]*lef[i]*rig[i];
	}
	cout<<ans<<endl;
	return 0;
}

104 no crossing

题目描述

在这里插入图片描述

题解

在这里插入图片描述
如图,按照要求,我们只能这样走,每次走完之后,之前所在的点就相当于障碍物,无法跨过。倘若我们走完之后,把整条路径反过来看:
在这里插入图片描述
对应下来就变为,倘若当前最后一步的端点是x,y,那么下一步要走的点必须在两个端点的外面。这样反过来的目的是为了方便递推。考虑区间dp,f[i][j][k][0/1]表示走了k步,现在经过的点的左端点是i,右端点是j,现在在i或者j时的最短路。直接递推即可。

代码

#include<bits/stdc++.h>
using namespace std;
const int N=110;
int f[N][N][N][2];//f i j k 0/1表示当前左端点在l,右端点在r,经过了k个节点,现在在左/右的最小值 
int n,K,m;
int dis[N][N];
int main(){
	memset(f,0x3f,sizeof(f));
	memset(dis,0x3f,sizeof(dis));
	scanf("%d%d%d",&n,&K,&m);
	for(int i=1;i<=m;i++){
		int x,y,z;scanf("%d%d%d",&x,&y,&z);
		int c=x;x=y;y=c;
		dis[x][y]=min(dis[x][y],z);
		if(x<y){
			f[x][y][2][1]=min(f[x][y][2][1],z);
		}else{
			f[y][x][2][0]=min(f[y][x][2][0],z);
		}
	}
	for(int k=2;k<K;k++){
		for(int i=1;i<=n;i++){
			for(int j=i+1;j<=n;j++){
				for(int l=1;l<i;l++){
					f[l][j][k+1][0]=min(f[l][j][k+1][0],f[i][j][k][0]+dis[i][l]);
					f[l][j][k+1][0]=min(f[l][j][k+1][0],f[i][j][k][1]+dis[j][l]);
				}
				for(int r=j+1;r<=n;r++){
					f[i][r][k+1][1]=min(f[i][r][k+1][1],f[i][j][k][0]+dis[i][r]);
					f[i][r][k+1][1]=min(f[i][r][k+1][1],f[i][j][k][1]+dis[j][r]);
				}
			}
		}
	}
	int ans=1e7;
	for(int i=1;i<=n;i++){
		for(int j=i+1;j<=n;j++){
			ans=min(ans,f[i][j][K][0]);
			ans=min(ans,f[i][j][K][1]);
		}
	}
	if(K==1){
		cout<<0<<endl;
		return 0;
	}
	if(ans==1e7){
		cout<<-1<<endl;
	}else{
		cout<<ans<<endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Chrome插件中使用可移动的div元素,可以使用以下步骤: 1.在插件的popup.html文件中,创建一个div元素,并为其添加一个唯一的ID,以便在JavaScript中引用它。 2.在CSS中,使用“position: absolute”属性将div定位在popup窗口的任何位置。 3.在JavaScript中,使用鼠标事件(mousedown、mousemove、mouseup)来实现拖动功能。当鼠标按下时,记录当前鼠标位置和div位置,然后在鼠标移动时计算新的div位置,并更新div的样式。 以下是一个简单的示例代码,可以帮助你在Chrome插件中实现可移动的div元素: popup.html代码: ``` <!DOCTYPE html> <html> <head> <title>My Extension</title> <style> #draggable { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 200px; height: 200px; background-color: #f2f2f2; border: 2px solid #ccc; text-align: center; line-height: 200px; cursor: move; } </style> </head> <body> <div id="draggable">Drag me!</div> <script src="popup.js"></script> </body> </html> ``` popup.js代码: ``` var draggable = document.getElementById('draggable'); var isDragging = false; var mouseX = 0; var mouseY = 0; var boxX = 0; var boxY = 0; draggable.addEventListener('mousedown', function(e) { isDragging = true; mouseX = e.clientX; mouseY = e.clientY; boxX = draggable.offsetLeft; boxY = draggable.offsetTop; }); document.addEventListener('mousemove', function(e) { if (isDragging) { var deltaX = e.clientX - mouseX; var deltaY = e.clientY - mouseY; draggable.style.left = boxX + deltaX + 'px'; draggable.style.top = boxY + deltaY + 'px'; } }); document.addEventListener('mouseup', function(e) { isDragging = false; }); ``` 在以上代码中,我们使用“cursor: move”属性将鼠标指针设置为拖动指针,以便用户知道该元素可以拖动。当用户按下鼠标时,我们记录当前鼠标位置和div的位置。然后,在鼠标移动时,我们计算新的div位置,并使用样式更新div的位置。最后,在鼠标松开时,我们将“isDragging”标志设置为false,以停止拖动。 请注意,在Chrome插件中,我们需要将JavaScript代码单独放在一个popup.js文件中,并在popup.html中引用它。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值