E. Hammer to Fall

E. Hammer to Fall

题目连接
本题主要在意的是转移锤子落下的城市的人到其他城市的成本,由此,只需要求出所有锤子落下的城市转移到其他安全城市的最小成本,再乘上该城市的人数即可,完成求解。

如果从锤子头遍历到锤子尾,前者可能会干预后者产生影响,由此采用倒序dp。

如果全部遍历的话,时间复杂度O(q*m)最坏 差不多10^10, 预计20秒左右,显然时间不达标,好点

为了节省时间,和提高效率,采用了根号分治和时间分块的理念来进行处理。

对于度大于( blog = sqrt(m) )的节点,,只看它前blog最小成本的转移。

每当转移了blog次后,更新维护的dp数组,保证信息是最新的。

每到blog天,就使用nth_element O(n)进行更新,时间复杂度为 q*m/blog ;
总体时间复杂度 : q ∗ b l o g + q ∗ m b l o g 总体时间复杂度: q*blog+\frac{q*m}{blog} 总体时间复杂度:qblog+blogqm

当 b l o g = m 时,总体时间复杂度为 : O ( q ∗ m ) 当blog=\sqrt{m}时,总体时间复杂度为:O(q*\sqrt{m}) blog=m 时,总体时间复杂度为:O(qm )

这样的时间复杂度最坏的情况下,有10^7.5次,小于5亿,显然在一秒以内。合情合理

#include<bits/stdc++.h> 
using namespace std;
using LL = long long;
using pil = pair<int,int>;
const int lim  = 1e5+10;
const LL INF =  LLONG_MAX;
const LL mod  = 998244353;
int a[lim]; 
int b[lim];
int deg[lim];
LL dp[lim];
int blo;
vector<pil> g[lim];
int main(){
	int n,m,q;
	cin>>n>>m>>q;
	blo = sqrt(m); //求出分届点
	for(int i=1;i<=n;i++) cin>>a[i];//输入人数
	int u,v,w;
	for(int i=1;i<=m;i++) 
	{
		cin>>u>>v>>w;
		g[u].emplace_back(v,w);
		g[v].emplace_back(u,w);
		deg[u]++;
		deg[v]++;
	}
	for(int i=q;i>=1;i--) cin>>b[i]; //倒着输入锤子落下点,方便进行倒叙dp
	
	for(int i=1;i<=n;i++)if(deg[i]>blo) //对度数大于blo的点,进行nth_element排序,按照规定的想法以该blog,分开两部分【在该lambdal表达式中,想要的是最小花费代价的转移点】
	{
		nth_element(g[i].begin(),g[i].begin()+blo,g[i].end(),[](const pil&x,const pil&y)
		{
			return dp[x.first]	+x.second < dp[y.first]	+y.second;
		}); 
	}
	
	for(int i=1;i<=q;i++)
	{
		int x = b[i];
		dp[x] = INF;
        //倒叙求出每个最小的成本
		for(int j=0;j<min(deg[x],blo);j++)	dp[x] = min(dp[x],dp[g[x][j].first]+g[x][j].second);
        //每当blog次时,更新当前最新前blog个最小成本信息。
		if(i%blo==0)
		{
			for(int i=1;i<=n;i++)if(deg[i]>blo)
			{
				nth_element(g[i].begin(),g[i].begin()+blo,g[i].end(),[](const pil&x,const pil&y)
				{
					return dp[x.first]	+x.second < dp[y.first]	+y.second;
				}); 
			}
		}
	}
	int ans = 0;
	for (int i = 1; i <= n; ++i) ans = (ans + a[i] * dp[i]) % mod;
    cout << ans << endl;
}
  • 11
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Hammer.js是一个用于处理触摸手势的JavaScript库,它提供了丰富的手势事件和手势识别功能。而pdf.js是Mozilla开发的一个用于在Web上显示PDF文件的JavaScript库。 要在使用Hammer.js实现手势缩放pdf.js的功能,你可以按照以下步骤进行操作: 1. 引入Hammer.js和pdf.js的库文件到你的HTML页面中。 2. 创建一个用于显示PDF文件的容器元素,例如一个div元素。 3. 使用pdf.js加载并显示PDF文件到容器元素中。 4. 初始化Hammer.js,并将其绑定到PDF容器元素上。 5. 监听Hammer.js的手势事件,例如pinch(缩放)事件。 6. 在手势事件的回调函数中,根据手势的缩放比例来调整PDF的显示大小。 下面是一个简单的示例代码: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Hammer.js手势缩放PDF.js</title> <script src="path/to/hammer.js"></script> <script src="path/to/pdf.js"></script> </head> <body> <div id="pdfContainer"></div> <script> // 加载并显示PDF文件 pdfjsLib.getDocument('path/to/pdf_file.pdf').promise.then(function(pdf) { pdf.getPage(1).then(function(page) { var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); var viewport = page.getViewport({ scale: 1 }); canvas.width = viewport.width; canvas.height = viewport.height; page.render({ canvasContext: context, viewport: viewport }); document.getElementById('pdfContainer').appendChild(canvas); }); }); // 初始化Hammer.js并绑定到PDF容器元素 var pdfContainer = document.getElementById('pdfContainer'); var hammer = new Hammer(pdfContainer); // 监听pinch(缩放)事件 hammer.on('pinch', function(event) { var scale = event.scale; // 获取缩放比例 // 根据缩放比例调整PDF的显示大小 var canvas = document.querySelector('#pdfContainer canvas'); var context = canvas.getContext('2d'); var viewport = page.getViewport({ scale: scale }); canvas.width = viewport.width; canvas.height = viewport.height; page.render({ canvasContext: context, viewport: viewport }); }); </script> </body> </html> ``` 希望以上代码能帮助到你实现Hammer.js手势缩放pdf.js的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值