SEG线段树

    xiaoxiao2026-10-05  2

    有一棵这样的线段树: mid不再等于(l+r)/2,而是l~r中的某个数,(代表什么呢,这棵树不是lgn级别的)…..询问区间中完整区间的个数


    分析: 可以转化为区间计数问题 用区间长度为1的区间个数减去所有区间长度不为1的区间个数 可以用树状数组维护: 把询问按照l从大到小排序,然后查询r的个数


    代码如下:

    #include<algorithm> #include<iostream> #include<cstring> #include<cstdio> using namespace std; const int maxn=100000+5; int n,m,hd[maxn],to[maxn],nxt[maxn],cnt,tree[maxn],ans[maxn]; struct lala{ int l,r,index; friend bool operator < (lala a,lala b){ return a.l<b.l; } }s[maxn]; inline void add(int x,int y){ to[cnt]=y; nxt[cnt]=hd[x]; hd[x]=cnt++; } inline void build(int l,int r){ if(l==r) return; int mid; add(l,r); scanf("%d",&mid); build(l,mid),build(mid+1,r); } inline void insert(int x,int y){ for(;x<=n;x+=(x&(-x))) tree[x]+=y; } inline int query(int x){ int sum=0; for(;x;x-=(x&(-x))) sum+=tree[x]; return sum; } signed main(void){ scanf("%d%d",&n,&m); memset(hd,-1,sizeof(hd)),cnt=0; build(1,n); for(int i=1;i<=m;i++){ s[i].index=i; scanf("%d%d",&s[i].l,&s[i].r); } sort(s+1,s+m+1); for(int i=n,k=m;i>=1;i--){ for(int j=hd[i];j!=-1;j=nxt[j]) insert(to[j],1); while(s[k].l==i) ans[s[k].index]=s[k].r-s[k].l+1-query(s[k].r),k--; } for(int i=1;i<=n;i++) printf("%d\n",ans[i]); return 0; }

    by >_< neighthorn

    转载请注明原文地址: https://ju.6miu.com/read-1312629.html
    最新回复(0)