cf1234 Round #590 Div3-D【二维树状数组】

这段代码展示了一种利用位运算优化的字符串操作方法,主要处理两种操作:将指定位置的字符替换为另一个字符,以及计算字符串子区间内不同字符的数量。通过建立26棵BIT(二进制指数树),可以高效地进行字符计数和更新。

Date:2021.01.06

题意:
操作1:将第pos个位置改为字母c
操作2:计算[l,r]中字母种类数

思路:建26个BIT,编号0-25。设原序列为s,操作1即为在第s[pos]-‘a’个BIT中将第pos个位置-1;再在第c-'a’个BIT中将第pos个位置+1。操作2即为统计26棵BIT上有几个在[l,r]上的和>0。【注意BIT下标从1开始,别忘了初始化。】
代码如下:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e5+10;
typedef long long LL;
LL n,t,tr[26][N];
char c[N];
LL lowbit(LL x)
{
    return x&-x;
}
void add(LL x,LL c,LL *tr)
{
    for(int i=x;i<=n;i+=lowbit(i)) tr[i]+=c; 
}
LL sum(LL x,LL *tr)
{
    LL res=1;
    for(int i=x;i;i-=lowbit(i)) res+=tr[i];
    return res;
}
int main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    cin>>c+1;n=strlen(c+1);
    for(int i=1;i<=n;i++) add(i,1,tr[c[i]-'a']);
    cin>>t;
    while(t--)
    {
        int op,l,r;char q;cin>>op;
        if(op==1)
        {
            cin>>l>>q;
            add(l,-1,tr[c[l]-'a']);
            add(l,1,tr[q-'a']);
            c[l]=q;
        }
        else
        {
            LL ans=0;
            cin>>l>>r;
            for(int i=0;i<26;i++)
            {
                LL ss=sum(r,tr[i])-sum(l-1,tr[i]);
                if(ss>0) ans++;
            }
            cout<<ans<<endl;
        }
    }
    return 0;
}
我的以下代码实现了绘制一个点位的功能,现在需要将ds文件中,包含的所有点位,都读取出来,一次性的绘制在这一个图层上,请修改代码 def plot_concentration_field_all_time02(ds, pointspec_idx=0, height_idx=0): """ 绘制同一释放点、同一高度层所有时间步的浓度总和(单图层绘制,颜色由总浓度决定) :param ds: xarray Dataset(FLEXPART输出) :param pointspec_idx: 释放点索引(0-13) :param height_idx: 高度层索引(0-3) """ # -------------------------- # 1. 提取固定释放点和高度层的所有时间步数据 # -------------------------- conc_data = ds[&#39;spec001_mr&#39;].isel( nageclass=0, pointspec=pointspec_idx, height=height_idx ) # 形状:(time, lat, lon) # 打印调试信息(关键!) # print("conc_data 原始形状:", conc_data.shape) # 应输出 (216, 200, 200) # -------------------------- # 2. 时间维度求和:得到二维总浓度场 # -------------------------- sum_conc = conc_data.sum(dim=&#39;time&#39;) # 每个(lat, lon)的所有时间步浓度累加 sum_conc_values = sum_conc.values # 提取numpy数组 # print("sum_conc_values 形状:", sum_conc_values.shape) # 应输出 (200, 200) # 定义阈值(低于100的区域不显示) threshold = 10 # 生成掩码:小于100的区域标记为True(需要屏蔽) mask = sum_conc_values < threshold # 生成masked数组(屏蔽小于100的区域) masked_sum_conc = np.ma.masked_where(mask, sum_conc_values) # -------------------------- # 3. 定义总浓度的颜色映射与分档 # -------------------------- cmap = plt.get_cmap(&#39;Blues&#39;) # 可替换为&#39;viridis&#39;/&#39;hot&#39;等色卡 # 分档边界:覆盖总浓度的最小-最大值 levels = np.linspace(sum_conc.min().values, sum_conc.max().values, 10) # -------------------------- # 4. 初始化画布和地图投影 # -------------------------- fig = plt.figure(figsize=(16, 12)) ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree()) set_dynamic_extent(ax, region_code=&#39;370800&#39;, buffer=0.05) # 自定义区域范围函数 # -------------------------- # 6. 绘制地理要素(zorder低于浓度场,确保在底层) # -------------------------- zorderidx = 1 logger.info(f&#39;正在绘制地图上乡镇边界&#39;) # 绘制乡镇街道边界 plot_street_shpfile(&#39;&#39;, ax, &#39;&#39;, &#39;&#39;, fig, zorderidx) zorderidx += 1 logger.info(f&#39;正在绘制地图上区县轮廓&#39;) # 绘制全国县城 plot_china_countys(&#39;&#39;, ax, &#39;&#39;, &#39;&#39;, fig, zorderidx) zorderidx += 1 logger.info(f&#39;正在绘制地图上城市边界&#39;) # 绘制城市边界 plot_city_boundaries(&#39;&#39;, ax, zorderidx, region_code=&#39;370800&#39;) zorderidx += 1 logger.info(f&#39;正在绘制地图上网格&#39;) # 画经纬度网格线 plot_gridline(&#39;&#39;, ax, &#39;lon&#39;, &#39;lat&#39;, fig, zorderidx) zorderidx += 1 # -------------------------- # 5. 单次绘制总浓度场(替代循环叠加) # -------------------------- # 生成经纬度网格(二维) lon = sum_conc.longitude.values lat = sum_conc.latitude.values # lon_2d, lat_2d = np.meshgrid(lon, lat, indexing=&#39;ij&#39;) ax.contourf( lon, lat, masked_sum_conc, levels=levels, # 总浓度的分档边界 cmap=cmap, # 颜色映射 transform=ccrs.PlateCarree(), # 数据投影 alpha=1, # 固定透明度(避免叠加浑浊) zorder=0 # 确保浓度场在地理要素上方 ) # -------------------------- # 7. 颜色条(仅显示总浓度范围) # -------------------------- cbar = plt.colorbar( plt.cm.ScalarMappable(cmap=cmap, norm=plt.Normalize(vmin=levels[0], vmax=levels[-1])), ax=ax, shrink=0.8, label=&#39;总浓度&#39; ) # -------------------------- # 8. 标题与标注 # -------------------------- relcom = bytes(ds.RELCOM[pointspec_idx].values).decode().strip().replace(&#39;city&#39;, &#39;&#39;) start_time = datetime.utcfromtimestamp( ds.time.isel(time=0).values.astype(&#39;datetime64[s]&#39;).astype(int) ) end_time = datetime.utcfromtimestamp( ds.time.isel(time=-1).values.astype(&#39;datetime64[s]&#39;).astype(int) ) plt.suptitle(&#39;FLEXPART 单释放点污染物扩散总浓度图&#39;, fontsize=18, fontweight=&#39;bold&#39;, y=0.96) plt.title(f&#39;释放点: {relcom.upper()}, 高度: {ds.height.isel(height=height_idx).values:.0f}m\n&#39; f&#39;时间范围: {start_time.strftime("%Y-%m-%d %H:%M")} 至 {end_time.strftime("%Y-%m-%d %H:%M")}&#39;, fontsize=14, pad=15) # -------------------------- # 9. 保存图像 # -------------------------- plt.savefig(&#39;single_release_point_total_conc.png&#39;, dpi=300, bbox_inches=&#39;tight&#39;) plt.close(fig)
09-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值