cf1527 c Sequence Pair Weight

这篇博客介绍了如何解决一道算法竞赛题目,该题目要求计算给定序列所有子序列的贡献度之和。贡献度定义为相同数字对的数量。博主首先提供了暴力求解的方法,然后通过优化,利用前缀和和离散化技术减少时间复杂度。最终实现了在限制时间内求解问题的高效算法。

Problem - C - Codeforces

题目大意:给定一串序列,求出它所有子序列的贡献度之和

贡献度:某个字串{1,1,2,2,1}中相同数字的对数{i,j}(i<j,下同)

即{1,2} {3,4} {1,5} {2,5},贡献度为4

在t了十几发之后终于切了这题

题解来了:

找出一对{a[i],a[j]},则包含i……j的子串都能被这对{a[i],a[j]}所贡献,i前面有i-1个数字,j后面有n-j个数字,组合起来一共有i*(n-j+1)种情况是包含i……j的子串,这些字串都能提供一个贡献值

暴力:双层for求出每对{a[i],a[j]}的贡献值,求和

然后第一个T就来了

那在进行优化

我们得到了i*(n-j+1)这个式子,那么当j不变的时候,存在一个或多个i符合条件,则j在后面的所有贡献值为(i1+i2+……)*(n-j+1)

所以我们考虑用前缀和来维护,将j从后往前搜索,搜到后把前缀和-j然后找下一个j

前缀和要记录a[j],可是a[j]<=1e9,明显数组会爆

但是我们高兴的发现n只有1e5,这时候我们可以考虑离散化,大于1e5的最小质数是100003,自己创建一种规则来把这些数字塞到数组里

我们考虑建一个二维数组,第一排记离散化前的数字,第二排记前缀和

思路大致就完成了

下面是代码

#include<bits/stdc++.h>
using namespace std;
long long  t[100005],k[100010][3];//t存序列,k是离散化
int main()
{
	std::ios::sync_with_stdio(false);
	cin.tie(NULL);
	long long n,a,i,z,y;
	cin>>n;
	while(n--)
	{
		cin>>a;
		if(a==2)
		{
			for(i=1;i<=a;i++) 
			{
			cin>>t[i];
			}
			if(t[1]==t[2]) cout<<1<<"\n";
			else cout<<0<<"\n";
			continue;
		}
		if(a==1) 
		{
			cin>>t[1];
			cout<<0<<"\n";
			continue;
		}
		memset(k,0,sizeof(k));
		memset(t,0,sizeof(t));
		y=0;
		for(i=1;i<=a;i++) 
		{
			z=0;
			cin>>t[i];
			if(t[i]<100003)
			{
				while(k[(t[i]+z)%100003][1]!=t[i]&&k[(t[i]+z)%100003][1]!=0)//离散化
				{
					z++; 
				}
				k[(t[i]+z)%100003][1]=t[i];
				k[(t[i]+z)%100003][2]+=i;
			}
			else
			{
				while(k[(t[i]%100003+z)%100003][1]!=t[i]&&k[(t[i]%100003+z)%100003][1]!=0)
				{
					z++;
				}
			k[(t[i]%100003+z)%100003][1]=t[i];
			k[(t[i]%100003+z)%100003][2]+=i;//前缀和
			}//离散化
			
		}
			for(i=a;i>=2;i--)
			{
				z=0;
					while(k[(t[i]%100003+z)%100003][1]!=t[i])
					{
						z++;
					}
					if(k[(t[i]%100003+z)%100003][1]!=0&&k[(t[i]%100003+z)%100003][2]!=i)
					{
					y+= (k[(t[i]%100003+z)%100003][2]-i)*(a-i+1);
					k[(t[i]%100003+z)%100003][2]=k[(t[i]%100003+z)%100003][2]-i; 
					}
			}
		cout<<y<<"\n";
			} 
}

 

 

上面代码运行后提示python里面不包含openrouteservice 的模块,需要按照以下代码的调用格式进行改进: import requests import json import folium import pandas as pd import numpy as np from datetime import datetime import webbrowser import os import math class OpenRouteService: def __init__(self, api_key): self.api_key = api_key self.base_url = "https://api.openrouteservice.org" def get_directions(self, coordinates, profile='driving-car'): """获取路径规划""" headers = { 'Authorization': self.api_key, 'Content-Type': 'application/json' } body = { "coordinates": coordinates, "instructions": "false", "geometry": "true" } print("正在调用OpenRouteService API...") try: response = requests.post( f"{self.base_url}/v2/directions/{profile}/geojson", json=body, headers=headers, timeout=30 ) if response.status_code == 200: print("API调用成功!") return response.json() else: print(f"API调用失败: {response.status_code}") print(f"错误信息: {response.text}") return None except Exception as e: print(f"API请求异常: {e}") return None def parse_route_data(ors_result, timestamps): """解析路由数据并计算速度""" if not ors_result or 'features' not in ors_result or not ors_result['features']: print("未找到有效的路径数据") return None, None, None, None feature = ors_result['features'][0] geometry = feature['geometry'] properties = feature.get('properties', {}) # 提取路径坐标 route_coords = [] if geometry['type'] == 'LineString': # 转换坐标顺序: [经度, 纬度] -> (纬度, 经度) route_coords = [(coord[1], coord[0]) for coord in geometry['coordinates']] # 检查是否有segments数据 if 'segments' not in properties or not properties['segments']: print("警告: 返回的数据中没有segments信息,使用简化计算") # 使用简化方法计算距离和速度 return calculate_simple_speed(route_coords, timestamps) # 提取分段信息 segments = properties['segments'][0] total_distance = segments.get('distance', 0) # 米 total_duration = segments.get('duration', 0) # 秒 # 计算平均速度 if total_duration > 0: avg_speed = (total_distance / total_duration) * 3.6 # km/h else: avg_speed = 0 print(f"路径总距离: {total_distance:.2f} 米") print(f"路径总时间: {total_duration:.2f} 秒") print(f"平均速度: {avg_speed:.2f} km/h") # 计算分段速度(如果有多个分段) step_speeds = [] step_distances = [] if 'steps' in segments: for step in segments['steps']: distance = step.get('distance', 0) duration = step.get('duration', 0) if duration > 0: speed = (distance / duration) * 3.6 else: speed = 0 step_speeds.append(speed) step_distances.append(distance) else: # 如果没有steps,使用总距离和总时间 if total_duration > 0: step_speeds.append(avg_speed) step_distances.append(total_distance) return route_coords, step_speeds, step_distances, avg_speed def calculate_simple_speed(route_coords, timestamps): """简化计算速度(当API返回数据不完整时使用)""" if not route_coords or len(route_coords) < 2: return None, None, None, 0 # 计算总距离(使用Haversine公式计算实际地理距离) total_distance = 0 for i in range(len(route_coords) - 1): # 使用Haversine公式计算两点间距离 lat1, lon1 = route_coords[i] lat2, lon2 = route_coords[i + 1] distance = haversine_distance(lon1, lat1, lon2, lat2) total_distance += distance # 计算总时间 total_duration = (timestamps[-1] - timestamps[0]).total_seconds() # 计算平均速度 if total_duration > 0: avg_speed = (total_distance / total_duration) * 3.6 # km/h else: avg_speed = 0 print(f"简化计算 - 路径总距离: {total_distance:.2f} 米") print(f"简化计算 - 路径总时间: {total_duration:.2f} 秒") print(f"简化计算 - 平均速度: {avg_speed:.2f} km/h") # 创建简化的分段数据 step_speeds = [avg_speed] # 使用平均速度作为分段速度 step_distances = [total_distance] # 使用总距离作为分段距离 return route_coords, step_speeds, step_distances, avg_speed def haversine_distance(lon1, lat1, lon2, lat2): """使用Haversine公式计算两点间距离(米)""" R = 6371000 # 地球半径(米) dlat = math.radians(lat2 - lat1) dlon = math.radians(lon2 - lon1) a = (math.sin(dlat / 2) * math.sin(dlat / 2) + math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) * math.sin(dlon / 2) * math.sin(dlon / 2)) c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)) return R * c def create_visualization(original_points, route_coords, step_speeds, person_id, output_dir="./output"): """创建可视化地图并保存结果""" if not os.path.exists(output_dir): os.makedirs(output_dir) # 创建地图 - 郑州大学为中心 center_lat = 34.817 # 郑州大学大致纬度 center_lon = 113.536 # 郑州大学大致经度 m = folium.Map(location=[center_lat, center_lon], zoom_start=15) # 添加原始点标记 for i, point in enumerate(original_points): folium.Marker( location=[point[1], point[0]], # (纬度, 经度) popup=f"人员 {person_id}<br>点 {i + 1}<br>经度: {point[0]:.6f}<br>纬度: {point[1]:.6f}", icon=folium.Icon(color='red', icon='user') ).add_to(m) # 添加路径 if route_coords: # 根据速度给路径着色 avg_speed = np.mean(step_speeds) if step_speeds else 0 if avg_speed < 1: color = 'gray' elif avg_speed < 3: color = 'blue' elif avg_speed < 5: color = 'green' elif avg_speed < 10: color = 'orange' else: color = 'red' folium.PolyLine( route_coords, color=color, weight=6, opacity=0.7, popup=f"人员 {person_id} 轨迹<br>平均速度: {avg_speed:.1f} km/h" ).add_to(m) # 添加起点终点标记 folium.Marker( location=route_coords[0], popup="起点", icon=folium.Icon(color='green', icon='play') ).add_to(m) folium.Marker( location=route_coords[-1], popup="终点", icon=folium.Icon(color='red', icon='stop') ).add_to(m) # 添加郑州大学标记 folium.Marker( location=[34.817, 113.536], popup="郑州大学", icon=folium.Icon(color='purple', icon='education') ).add_to(m) # 保存地图 map_file = os.path.join(output_dir, f"route_visualization_{person_id}.html") m.save(map_file) print(f"地图已保存至: {map_file}") return map_file def save_results_to_csv(original_points, route_coords, step_speeds, step_distances, timestamps, person_id, output_dir="./output"): """保存结果到CSV文件""" if not os.path.exists(output_dir): os.makedirs(output_dir) # 保存原始点数据 original_data = [] for i, point in enumerate(original_points): original_data.append({ 'person_id': person_id, 'point_id': i + 1, 'longitude': point[0], 'latitude': point[1], 'timestamp': timestamps[i] if i < len(timestamps) else None }) df_original = pd.DataFrame(original_data) original_csv = os.path.join(output_dir, f"original_points_{person_id}.csv") df_original.to_csv(original_csv, index=False, encoding='utf-8-sig') print(f"原始点数据已保存至: {original_csv}") # 保存路径点数据 if route_coords: route_data = [] for i, coord in enumerate(route_coords): route_data.append({ 'person_id': person_id, 'route_point_id': i + 1, 'latitude': coord[0], 'longitude': coord[1] }) df_route = pd.DataFrame(route_data) route_csv = os.path.join(output_dir, f"route_points_{person_id}.csv") df_route.to_csv(route_csv, index=False, encoding='utf-8-sig') print(f"路径点数据已保存至: {route_csv}") # 保存分段速度数据 if step_speeds and step_distances: speed_data = [] for i, (speed, distance) in enumerate(zip(step_speeds, step_distances)): speed_data.append({ 'person_id': person_id, 'segment_id': i + 1, 'distance_m': distance, 'speed_kmh': speed, 'start_time': timestamps[i] if i < len(timestamps) else None, 'end_time': timestamps[i + 1] if i + 1 < len(timestamps) else None }) df_speed = pd.DataFrame(speed_data) speed_csv = os.path.join(output_dir, f"segment_speeds_{person_id}.csv") df_speed.to_csv(speed_csv, index=False, encoding='utf-8-sig') print(f"分段速度数据已保存至: {speed_csv}") def open_map_in_browser(map_file): """在浏览器中打开地图""" try: webbrowser.open('file://' + os.path.abspath(map_file)) print("正在浏览器中打开地图...") except Exception as e: print(f"无法在浏览器中打开地图: {e}") print(f"请手动打开文件: {os.path.abspath(map_file)}") def parse_timestamp(timestamp_str): """解析时间戳字符串""" try: # 处理毫秒时间戳 if '.' in timestamp_str: return datetime.strptime(timestamp_str, '%Y-%m-%dT%H:%M:%S.%f') else: return datetime.strptime(timestamp_str, '%Y-%m-%dT%H:%M:%S') except Exception as e: print(f"时间解析错误: {e}") return datetime.now() def process_person_trajectory(person_data, api_key): """处理单个人的轨迹数据""" # 按时间排序 person_data.sort(key=lambda x: x['timestamp']) # 提取坐标和时间 coordinates = [[point['longitude'], point['latitude']] for point in person_data] timestamps = [point['timestamp'] for point in person_data] person_id = person_data[0]['person_id'] if person_data else "unknown" print(f"\n处理人员 {person_id} 的轨迹数据...") print(f"数据点数: {len(coordinates)}") ors = OpenRouteService(api_key) # 获取路径规划 result = ors.get_directions(coordinates) if result: # 解析数据 route_coords, step_speeds, step_distances, avg_speed = parse_route_data(result, timestamps) if route_coords: # 创建可视化 map_file = create_visualization(coordinates, route_coords, step_speeds, person_id) # 保存结果到CSV save_results_to_csv(coordinates, route_coords, step_speeds, step_distances, timestamps, person_id) # 在浏览器中打开地图 open_map_in_browser(map_file) print(f"\n=== 人员 {person_id} 处理完成 ===") print(f"• 可视化地图: {os.path.abspath(map_file)}") print(f"• 数据文件保存在: {os.path.abspath('./output')} 目录") return True else: print(f"无法解析人员 {person_id} 的路径数据") return False else: print(f"无法获取人员 {person_id} 的路径规划结果") return False # 使用示例 - 郑州大学轨迹分析 def zhengzhou_university_example(): # 替换为你的实际API密钥 api_key = "eyJvcmciOiI1YjNjZTM1OTc4NTExMTAwMDFjZjYyNDgiLCJpZCI6IjdjMjYxY2Q2NzgyNjRlYjViOWRiODBlOTIxZTE3NDA1IiwiaCI6Im11cm11cjY0In0=" if api_key == "YOUR_OPENROUTESERVICE_API_KEY": print("请先设置你的OpenRouteService API密钥!") return # 郑州大学实际点位数据 raw_data = [ "郑州大学点,2024-7-13T11:55:10,0000897851,113.529859103333,34.81229556", "郑州大学点,2024-7-13T12:00:33,0000897851,113.5240264075,34.813994935" ] # 解析数据 person_data = [] for line in raw_data: parts = line.split(',') if len(parts) >= 5: person_data.append({ 'location': parts[0], 'timestamp': parse_timestamp(parts[1]), 'person_id': parts[2], 'longitude': float(parts[3]), 'latitude': float(parts[4]) }) # 按人员ID分组处理(这里只有一个人员) persons = {} for data in person_data: person_id = data['person_id'] if person_id not in persons: persons[person_id] = [] persons[person_id].append(data) # 处理每个人的轨迹 success_count = 0 for person_id, data in persons.items(): if process_person_trajectory(data, api_key): success_count += 1 print(f"\n=== 总体处理完成 ===") print(f"成功处理 {success_count}/{len(persons)} 个人员的轨迹数据") print(f"所有结果保存在: {os.path.abspath('./output')} 目录") if __name__ == "__main__": zhengzhou_university_example() # 添加暂停,确保能看到输出 input("按Enter键退出...")
最新发布
11-21
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值