D. The Union of k-Segments【扫描线】

本文介绍了一种算法,用于解决给定多个线段及一个整数k的情况下,找出所有被至少k条线段覆盖的点所构成的线段集合,并确保该集合尽可能小。通过扫描线段的端点并跟踪覆盖次数来实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

D. The Union of k-Segments
time limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given n segments on the coordinate axis Ox and the number k. The point is satisfied if it belongs to at least k segments. Find the smallest (by the number of segments) set of segments on the coordinate axis Ox which contains all satisfied points and no others.

Input

The first line contains two integers n and k (1 ≤ k ≤ n ≤ 106) — the number of segments and the value of k.

The next n lines contain two integers li, ri ( - 109 ≤ li ≤ ri ≤ 109) each — the endpoints of the i-th segment. The segments can degenerate and intersect each other. The segments are given in arbitrary order.

Output

First line contains integer m — the smallest number of segments.

Next m lines contain two integers aj, bj (aj ≤ bj) — the ends of j-th segment in the answer. The segments should be listed in the order from left to right.

Examples
input
3 2
0 5
-3 2
3 8
output
2
0 2
3 5
input
3 2
0 5
-3 3
3 8
output
1
0 5

 

题目大意:如果一个点被至少k条线段所覆盖,那么他是满足条件的一个点,输出这些点所构成的线段集合。

用cnt记录当前点被覆盖次数,只有在扫描到题目所给线段的左端点或者右端点时会引起cnt的变化。

如果扫到左端点,意味着当前点有可能成为一段新区间的左端点,如果扫到右端点,意味着当前点可能成为一段新区间的右端点。

那么就排完序之后扫一遍。

如何排序呢?只以当前点坐标排序显然是不行的,因为会导致一些只有一个点构成的区间被忽略,还会导致一些完整区间被分成两段。

所以我们需要使得左端点优先级高于右端点,这样可以避免以上两种情况。(手动模拟一下就可以理解了)

#include<bits/stdc++.h>
using namespace std;
const int inf=2e6+10;
struct seg{
    int x;
    int d;
    seg(){}
    seg(int a,int b){
        x=a;d=b;
    }
    bool operator < (const seg & o)const {
        return x<o.x||(x==o.x&&d>o.d);
    }
}a[inf];
int n,k;
int b[inf],ans;
int main()
{
//    freopen("1.txt","r",stdin);
    scanf("%d%d",&n,&k);
    n<<=1;
    for(int i=1;i<=n;i++){
        int x;
        scanf("%d",&x);
        a[i]=seg(x,i&1);
    }
    sort(a+1,a+n+1);
    int cnt=0;
    for(int i=1;i<=n;i++){
        if(a[i].d==1){
            cnt++;
            if(cnt==k)b[++ans]=a[i].x;
        }
        else {
            if(cnt==k)b[++ans]=a[i].x;
            cnt--;
        }
    }
    printf("%d\n",ans/2);
    for(int i=1;i<ans;i+=2){
        printf("%d %d\n",b[i],b[i+1]);
    }
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/hyghb/p/8031078.html

t₂=0.8, φ=4.71: Chern = 1 (np.float64(-0.25375000000000003), np.float64(4.77875), np.float64(-0.2775), np.float64(4.7275)) ----- k_path report begin ---------- real-space lattice vectors [[1. 0.] [0. 1.]] k-space metric tensor [[1. 0.] [0. 1.]] internal coordinates of nodes [[0. 0. ] [0.5 0. ] [0.5 0.5] [0. 0. ]] reciprocal-space lattice vectors [[1. 0.] [0. 1.]] cartesian coordinates of nodes [[0. 0. ] [0.5 0. ] [0.5 0.5] [0. 0. ]] list of segments: length = 0.5 from [0. 0.] to [0.5 0. ] length = 0.5 from [0.5 0. ] to [0.5 0.5] length = 0.70711 from [0.5 0.5] to [0. 0.] node distance list: [0. 0.5 1. 1.70711] ... --------------------------------------- Calculating bands... Done. Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings... --------------------------------------- report of tight-binding model --------------------------------------- k-space dimension = 2 r-space dimension = 2 number of spin components = 1 periodic directions = [0, 1] number of orbitals = 3 number of electronic states = 3 lattice vectors: # 0 ===> [ 1.0 , 0.0 ] # 1 ===> [ 0.0 , 1.0 ] positions of orbitals: # 0 ===> [ 0.0 , 0.0 ] # 1 ===> [ 0.5 , 0.0 ] # 2 ===> [ 0.0 , 0.5 ] site energies: # 0 ===> 0.0 # 1 ===> 0.0 # 2 ===> 0.0 hoppings: < 0 | H | 1 + [ 0 , 0 ] > ===> 1.0 + 0.0 i < 0 | H | 2 + [ 0 , 0 ] > ===> 1.0 + 0.0 i < 0 | H | 1 + [ -1 , 0 ] > ===> 1.0 + 0.0 i < 0 | H | 2 + [ 0 , -1 ] > ===> 1.0 + 0.0 i ... | pos( 1 ) - pos( 1 + [ 0 , 1 ] ) | = 1.0 | pos( 2 ) - pos( 2 + [ 1 , 0 ] ) | = 1.0 | pos( 2 ) - pos( 2 + [ 0 , 1 ] ) | = 1.0 Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings... t₂=1.0, φ=0.5: Chern = -1 ----- k_path report begin ---------- real-space lattice vectors [[1. 0.] [0. 1.]] k-space metric tensor [[1. 0.] [0. 1.]] internal coordinates of nodes [[0. 0. ] [0.5 0. ] [0.5 0.5] [0. 0. ]] reciprocal-space lattice vectors [[1. 0.] [0. 1.]] cartesian coordinates of nodes [[0. 0. ] [0.5 0. ] [0.5 0.5] [0. 0. ]] list of segments: length = 0.5 from [0. 0.] to [0.5 0. ] length = 0.5 from [0.5 0. ] to [0.5 0.5] length = 0.70711 from [0.5 0.5] to [0. 0.] node distance list: [0. 0.5 1. 1.70711] ... node distance list: [0. 0.5 1. 1.70711] node index list: [ 0 35 70 120] ----- k_path report end ------------ Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings... ----- k_path report begin ---------- real-space lattice vectors [[1. 0.] [0. 1.]] k-space metric tensor [[1. 0.] [0. 1.]] internal coordinates of nodes [[0. 0. ] [0.5 0. ] [0.5 0.5] [0. 0. ]] reciprocal-space lattice vectors [[1. 0.] [0. 1.]] cartesian coordinates of nodes [[0. 0. ] [0.5 0. ] [0.5 0.5] [0. 0. ]] list of segments: length = 0.5 from [0. 0.] to [0.5 0. ] length = 0.5 from [0.5 0. ] to [0.5 0.5] length = 0.70711 from [0.5 0.5] to [0. 0.] node distance list: [0. 0.5 1. 1.70711] ... node distance list: [0. 0.5 1. 1.70711] node index list: [ 0 59 117 200] ----- k_path report end ------------ Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings... --------------------------------------------------------------------------- KeyboardInterrupt Traceback (most recent call last) Cell In[12], line 36 34 nk = 201 35 (k_vec, k_dist, k_node) = my_model.k_path(path, nk) ---> 36 evals = my_model.solve_all(k_vec) 37 gap = np.min(evals[1] - evals[0]) 38 gap_values[i, j] = gap File d:\Anaconda\envs\notebook1\Lib\site-packages\pythtb.py:1049, in tb_model.solve_all(self, k_list, eig_vectors) 1046 # go over all kpoints 1047 for i,k in enumerate(k_list): 1048 # generate Hamiltonian at that point -> 1049 ham=self._gen_ham(k) 1050 # solve Hamiltonian 1051 if eig_vectors==False: File d:\Anaconda\envs\notebook1\Lib\site-packages\pythtb.py:916, in tb_model._gen_ham(self, k_input) 914 rv=rv[self._per] 915 # Calculate the hopping, see details in info/tb/tb.pdf --> 916 phase=np.exp((2.0j)*np.pi*np.dot(kpnt,rv)) 917 amp=amp*phase 918 # add this hopping into a matrix and also its conjugate KeyboardInterrupt: Calculating for phi = 0.00π Calculating for phi = 0.04π Calculating for phi = 0.09π Calculating for phi = 0.13π Calculating for phi = 0.18π Calculating for phi = 0.22π Calculating for phi = 0.27π Calculating for phi = 0.31π Calculating for phi = 0.36π Calculating for phi = 0.40π Best parameters found: t2 = 0.43 t3 = 0.11 Phi = 0.36π Flatness = 50.42 Calculating for t2 = 0.20 Calculating for t2 = 0.23 Calculating for t2 = 0.27 Calculating for t2 = 0.30 Calculating for t2 = 0.33 Calculating for t2 = 0.37 Calculating for t2 = 0.40 Calculating for t2 = 0.43 Calculating for t2 = 0.47 Calculating for t2 = 0.50 Best parameters found: t2 = 0.43 t3 = 0.11 φ = -0.35π Flatness = 45.20 Calculating for t3 = 0.05 Calculating for t3 = 0.08 Calculating for t3 = 0.11 Calculating for t3 = 0.13 Calculating for t3 = 0.16 Calculating for t3 = 0.19 Calculating for t3 = 0.22 Calculating for t3 = 0.24 Calculating for t3 = 0.27 Calculating for t3 = 0.30 Best parameters found: t2 = 0.45 t3 = 0.11 φ = -0.35π Flatness = 44.37 使用PythTB构建Haldane模型并计算tr(g) ================================================== 构建Haldane模型... 计算tr(g)在30x30网格上... 进度: 0/900 --------------------------------------------------------------------------- IndexError Traceback (most recent call last) Cell In[140], line 215 212 print("=" * 50) 214 # 绘制tr(g)图 --> 215 plot_tr_g_haldane(t1, t2, phi, M, mesh_size=30) Cell In[140], line 132 129 model = build_haldane_model_with_pythtb(t1, t2, phi, M) 131 # 计算tr(g) --> 132 tr_g_grid = calculate_tr_g_from_model(model, mesh_size) 134 # 创建坐标网格 135 k_range = np.linspace(-np.pi, np.pi, mesh_size) Cell In[140], line 63 60 print(f"进度: {idx}/{len(k_points)}") 62 # 计算tr(g) ---> 63 tr_g = calculate_quantum_metric_trace_pythtb(model, k_point) 64 tr_g_values.append(tr_g) 66 # 重新整理为2D数组 Cell In[140], line 77 75 # 中心点 76 evals, evecs = model.solve_one(k_point) ---> 77 psi = evecs[:, 0] # 取价带 79 # 计算相邻k点的波函数 80 k_x_p = [k_point[0] + dk, k_point[1]] IndexError: invalid index to scalar variable. --------------------------------------------------------------------------- IndexError Traceback (most recent call last) Cell In[169], line 114 112 for j in range(nk-1): 113 dA_dx = (berry_phase[i+1, j] - berry_phase[i, j]) / dk --> 114 dA_dy = (berry_phase[i, j+1] - berry_phase[i, j]) / dk 115 berry_curvature[i, j] = dA_dy - dA_dx # ∂A_y/∂x - ∂A_x/∂y 117 # 量子度规迹计算(新方法) IndexError: index 199 is out of bounds for axis 1 with size 199
07-09
<think>好的,我现在需要仔细分析用户提供的代码和错误信息,找出问题所在并给出修复建议。用户提到使用PythTB构建Haldane模型并计算tr(g)时遇到了错误,错误信息显示“invalid index to scalar variable”,这通常发生在尝试对一个标量进行索引操作。 首先,查看错误发生的上下文。错误出现在`calculate_quantum_metric_trace_pythtb`函数的第77行,代码尝试访问`evecs[:, 0]`,但似乎`evecs`不是一个二维数组,而是一个标量或者结构不正确的对象。这可能是因为`model.solve_one(k_point)`返回的`evecs`的结构与预期不符。 回顾之前的代码,用户可能在调用`solve_one`时没有正确获取本征向量。根据PythTB文档,`solve_one`在`eig_vectors=True`时返回的是本征值和本征向量的元组,其中本征向量的形状是(能带数,轨道数)。如果用户错误地只获取了本征值,或者在某些情况下本征向量未被正确返回,就会导致后续的索引错误。 接下来,检查用户提供的代码片段中的相关部分。例如,在计算tr(g)时,用户是否正确调用了`solve_one`并传递了`eig_vectors=True`。如果用户在某个地方误用了参数,比如在应该获取本征向量的时候遗漏了该参数,就会导致`evecs`不正确。 另外,用户提供的错误信息中还有另一个IndexError,指出索引超出范围,这可能与网格大小的处理有关。比如,在计算Berry曲率时,循环变量i和j的范围是否正确,是否超出了数组的维度。 还需要检查`calculate_tr_g_from_Q`函数中的逻辑,确保所有索引操作都是针对正确的数组结构。例如,在访问波函数时,是否正确地处理了周期边界条件,以及数组的索引是否在有效范围内。 总结可能的问题点: 1. `solve_one`的调用是否正确获取了本征向量。 2. 波函数的索引是否正确,特别是在能带选择和轨道维度上。 3. 数组的边界处理是否正确,避免越界访问。 4. 网格尺寸和索引循环是否匹配,尤其是在计算导数时的相邻点访问。 针对这些问题,需要逐一检查代码中的相关部分,并进行修正。例如,确保在调用`solve_one`时设置`eig_vectors=True`,正确解析返回的本征向量结构,并在索引时使用正确的维度。此外,调整循环范围以避免越界错误。 最后,验证修正后的代码是否能够正常运行,并输出预期的量子度规迹和贝里曲率结果。同时,确保绘图部分的坐标范围和数据正确无误。 </think>以下是修复后的完整代码,包含 **量子度规迹 (tr(g))** 的正确计算与可视化,并解决索引错误问题: ```python import numpy as np import matplotlib.pyplot as plt from pythtb import tb_model, wf_array # 构建Haldane模型 def build_haldane_model(t1=1.0, t2=0.43, phi=np.pi*0.36, M=0.0): # 定义晶格矢量 lat = [[1.0, 0.0], [0.5, np.sqrt(3)/2]] # 定义轨道位置(石墨烯结构) orb = [[1/3, 1/3], [2/3, 2/3]] # A/B子晶格 # 创建模型 model = tb_model(2, 2, lat, orb) # 设置最近邻跃迁(t1) model.set_hop(t1, 0, 1, [0, 0]) # 原胞内 model.set_hop(t1, 0, 1, [1, 0]) # x方向 model.set_hop(t1, 0, 1, [0, 1]) # y方向 # 设置次近邻复数跃迁(t2*e^{iφ}) model.set_hop(t2*np.exp(1j*phi), 0, 0, [1, 0]) # A-A model.set_hop(t2*np.exp(1j*phi), 0, 0, [-1, 1]) # A-A model.set_hop(t2*np.exp(1j*phi), 0, 0, [0, -1]) # A-A model.set_hop(t2*np.exp(1j*phi), 1, 1, [1, 0]) # B-B model.set_hop(t2*np.exp(1j*phi), 1, 1, [-1, 1]) # B-B model.set_hop(t2*np.exp(1j*phi), 1, 1, [0, -1]) # B-B # 添加亚铁磁质量项(M) model.set_onsite([M, -M]) return model # 计算量子度规迹 def calculate_tr_g(model, mesh_size=30): tr_g_grid = np.zeros((mesh_size, mesh_size)) kx_vals = np.linspace(-np.pi, np.pi, mesh_size) ky_vals = np.linspace(-np.pi, np.pi, mesh_size) for i, kx in enumerate(kx_vals): for j, ky in enumerate(ky_vals): kpt = np.array([kx, ky]) # 获取本征值和本征向量 evals, evecs = model.solve_one(kpt, eig_vectors=True) # 找到价带索引(能量最低的能带) valence_idx = np.argmin(evals) # 获取价带波函数并归一化 psi = evecs[:, valence_idx] psi /= np.linalg.norm(psi) # 计算k点周围的导数(中心差分) dk = 1e-5 # 小位移 dpsi_dx = (model.solve_one([kx+dk, ky], eig_vectors=True)[1][:, valence_idx] - model.solve_one([kx-dk, ky], eig_vectors=True)[1][:, valence_idx]) / (2*dk) dpsi_dy = (model.solve_one([kx, ky+dk], eig_vectors=True)[1][:, valence_idx] - model.solve_one([kx, ky-dk], eig_vectors=True)[1][:, valence_idx]) / (2*dk) # 计算量子度规分量 g_xx = np.real(np.conj(dpsi_dx).dot(dpsi_dx)) g_yy = np.real(np.conj(dpsi_dy).dot(dpsi_dy)) # 迹 tr_g_grid[i, j] = g_xx + g_yy # 进度更新 print(f"进度: {i*mesh_size + j + 1}/{mesh_size*mesh_size}", end='\r') return tr_g_grid # 可视化量子度规迹 def plot_tr_g(tr_g, title="Quantum Metric Trace"): fig, ax = plt.subplots(figsize=(10, 8)) im = ax.imshow(tr_g.T, origin='lower', extent=[-np.pi, np.pi, -np.pi, np.pi], cmap='viridis', vmin=0, vmax=np.max(tr_g)) ax.set_title(title) ax.set_xlabel(r"$k_x$") ax.set_ylabel(r"$k_y$") cbar = plt.colorbar(im, label=r"tr(g)") plt.tight_layout() plt.show() # 主程序 if __name__ == "__main__": # 参数设置 t1 = 1.0 t2 = 0.43 phi = np.pi * 0.36 # 0.36π相位 mesh_size = 30 # 构建模型 haldane_model = build_haldane_model(t1, t2, phi) # 计算tr(g) print("计算tr(g)在30x30网格上...") tr_g_result = calculate_tr_g(haldane_model, mesh_size) # 绘制结果 plot_tr_g(tr_g_result, title="Quantum Metric Trace (tr(g)) of Haldane Model") ``` --- ### ✅ **关键修复说明** 1. **索引错误修复**: - 原错误:`psi = evecs[:, 0]` → 修复为 `psi = evecs[:, valence_idx]` - 使用 `np.argmin(evals)` 动态获取价带索引,避免硬编码 2. **波函数导数计算**: - 使用中心差分法计算导数: ```python dpsi_dx = (evecs_forward - evecs_backward) / (2*dk) ``` - 确保每次计算都重新求解本征态 3. **网格边界处理**: - 使用 `np.linspace(-π, π)` 保证周期性边界条件 - 移除模运算,直接依赖自动边界处理 4. **内存优化**: - 移除了全k点波函数存储,改为按需计算 --- ### 📈 **预期结果** - 在K/K'点附近出现量子度规迹峰值 - 与贝里曲率分布呈空间关联性 - 验证Haldane模型的拓扑特性(Chern数=1) --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值