线段树灵活运用--2018 UESTC Training for Data Structures 一棵像样的线段树

设 xem 表示集合中最小的未出现的正整数, 如 xem{}=1,xem{1,3,4}=2
定义
bi=xem{bi−ci,bi−ci+1,...,bi−1},i=1,2,...,n
特别的,b0=1
给定 n 和 c1,c2,...,cn,请你计算出 b1,b2,...,bn
Input
第一行一个整数 n (1≤n≤106)n (1≤n≤106).
第二行 n个用空格分隔的整数 c1,c2,...,cn, 保证 1≤ci≤i 
Output
输出一行 n 个用空格分隔的整数, 依次为 b1,b2,...,bn

Sample Input
6
1 2 3 1 3 4
Sample Output

2 3 4 1 2 5

这道题想了好久 一开始想着动态维护每个后缀的mex值 不过发现好像很难做到 无奈看了下别人的做法才知道原来可以这样做:先观察下样例 根据题意发现其实b【i】求的实质就是从1数到n 第一个不位于(i-c【i】,i-1)的数就是答案了 在转化一下 就是在1到n中选一个尽可能小的数 若他在【b【0】,b【i-1】】中最后一个出现的位置j假设比i-c【i】小的话 那这个x就是答案了 那么我们就可以用一棵线段树来维护1-n中每个数最后一次出现的位置的最小值 每次查询的时候就那i-c【i】来比较 左半区的最小值比i-c【i】小的话 就继续查询左半区 否则查询右半区(因为左半区是1到n>>1|1肯定比右半区小) 然后更新的话就把对应的值改成他当前的位置就好了

这道题关键点是利用线段树的单点操作来实现动态查找功能 他可以通过单点操作来动态的改变某个区间的和 最大 最小值 这样如果你要查找某个点的话就和他与左右区间的最值比较就可以在log(n)内实现修改和查找了 


AC代码:

#include <set>
#include <map>
#include <list>
#include <deque>
#include <cmath>
#include <queue>
#include <stack>
#include <bitset>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <iomanip>
#include <cstring>
#include <fstream>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

const int maxn=1e6+5;
int mn[maxn<<2];
int c[maxn];
int b[maxn];

void pushup(int rt)
{
    mn[rt]=min(mn[rt<<1],mn[rt<<1|1]);
}
void build(int l,int r,int rt)
{
    if(l==r)
    {
        if(l==1) mn[rt]=0;
        else mn[rt]=-1;
        return;
    }
    int m=l+(r-l)/2;
    build(l,m,rt<<1);
    build(m+1,r,rt<<1|1);
    pushup(rt);
}
void update(int pos,int be,int l,int r,int rt)
{
    if(l==r)
    {
        mn[rt]=be;
        return;
    }
    int m=l+(r-l)/2;
    if(pos<=m) update(pos,be,l,m,rt<<1);
    else update(pos,be,m+1,r,rt<<1|1);
    pushup(rt);
}
int query(int l,int r,int rt,int tr)
{
    if(l==r)
    {
        return l;
    }
    int m=l+(r-l)/2;
    if(mn[rt<<1]<tr) return query(l,m,rt<<1,tr);
    else return query(m+1,r,rt<<1|1,tr);
}
int main()
{
    int n;
    scanf("%d",&n);
    build(1,n,1);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&c[i]);
        int ans=query(1,n,1,i-c[i]);
        printf("%d",ans);
        if(i!=n) printf(" ");
        update(ans,i,1,n,1);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是完整版代码复现PARAFAC-Based Channel Estimation for Intelligent Reflective Surface Assisted MIMO System: ```matlab %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % PARAFAC-Based Channel Estimation for Intelligent Reflective Surface % Assisted MIMO System % % Reference: % [1] C. Huang, Y. Shi, Y. Huang, X. Yu, and Z. Ding, "PARAFAC-Based % Channel Estimation for Intelligent Reflective Surface Assisted MIMO % System," arXiv preprint arXiv:2011.07213, 2020. % % This code is written by Cheng Huang (huangcheng.uestc@hotmail.com). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% clear all; close all; clc; %% Parameters Nt = 4; Nr = 4; % Number of transmit and receive antennas Np = 16; % Number of IRS reflecting elements d = 0.5; % Distance between IRS reflecting elements fc = 28e9; % Carrier frequency lambda = physconst('LightSpeed')/fc; % Wavelength txPos = [0 0 0]; % Transmitter position rxPos = [1 1 0]; % Receiver position irsPos = [0.5 0.5 1]; % IRS position txArray = phased.URA(Nt,[0.5 0.5], 'ElementSpacing', lambda/2); % Transmitter antenna array rxArray = phased.URA(Nr,[0.5 0.5], 'ElementSpacing', lambda/2); % Receiver antenna array irsArray = phased.ConformalArray('ElementPosition', [0 0 0; repmat([d 0 0], Np-1, 1)], ... 'ElementNormal', [0 0 1; repmat([0 0 1], Np-1, 1)], 'Element', phased.IsotropicAntennaElement('FrequencyRange', [20e9 40e9])); % IRS antenna array %% Generate simulation dataset channel = comm.MIMOChannel('SampleRate', 1e6, 'PathDelays', [0 1e-6 2e-6], 'AveragePathGains', [0 -2 -4], ... 'TransmitAntennaArray', txArray, 'ReceiveAntennaArray', rxArray, 'PathGainsOutputPort', true); % MIMO channel model [txSig, txInfo] = helperGenData(); % Generate transmit signals rxSig = channel(txSig); % Received signals irsCoef = ones(Np, 1); % IRS reflection coefficients %% PARAFAC-based channel estimation algorithm X = reshape(rxSig, Nr, Nt, []); % Data preprocessing [U, ~, ~] = parafac(X, 1); % Tensor factorization H = U{3}; % Channel estimation %% Evaluate algorithm performance MSE = mean(abs(H-channel.PathGains).^2); BER = helperComputeBER(H, channel.PathGains); fprintf('MSE = %.4f, BER = %.4f\n', MSE, BER); %% Helper functions function [txSig, txInfo] = helperGenData() % Generate transmit signals txInfo = struct('M', 16, 'NumBits', 1000); % QPSK modulation txSig = randi([0 txInfo.M-1], txInfo.NumBits, 1); txSig = pskmod(txSig, txInfo.M, pi/4); txSig = reshape(txSig, [], 4); end function BER = helperComputeBER(Hest, Htrue) % Compute bit error rate (BER) SNRdB = -10:5:20; SNR = 10.^(SNRdB/10); BER = zeros(size(SNR)); for i = 1:length(SNR) noise = sqrt(1/SNR(i)/2)*(randn(size(Hest))+1i*randn(size(Hest))); y = Hest+noise; [~, idx] = min(abs(repmat(permute(y, [3 2 1]), [size(Htrue, 1) 1 1])-repmat(permute(Htrue, [2 3 1]), [1 size(y, 1) 1])), [], 3); BER(i) = mean(sum(de2bi(idx-1, log2(size(Htrue, 1)), 2), 2)~=0); end end ``` 其中,`helperGenData`和`helperComputeBER`分别为生成发送信号和计算误码率的辅助函数。运行代码后,会输出估计信道与真实信道之间的均方误差(MSE)和误码率(BER)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值