线段树模板二

来源:互联网 发布:看耳朵知健康 编辑:程序博客网 时间:2024/05/21 11:18
//线段数模板二  数组模拟版//功能:在自然数,且所有的数不大于30000的范围内讨论一个问题:现在已知n条线段,把端点//依次输入告诉你,然后有m个询问,每个询问输入一个点,要求这个点在多少条线段上出现#include <iostream>#include <cstdio>#include <cstdlib>using namespace std;struct treel{    int left,right;   // 左端点 右端点    int cover;} t[1001];int n,m;int sum=0;void build(int l,int r,int step){    t[step].left=l;    t[step].right=r;    t[step].cover=0;    if(l==r) return;    build(l,(l+r)/2,step*2);    build((l+r)/2+1,r,step*2+1);}void dfs(int step){    cout<<t[step].cover<<endl;    if(t[step].left==t[step].right) return;    dfs(step*2);    dfs(step*2+1);}void Insert(int c,int d,int step){    if(c==t[step].left&&d==t[step].right)    {        t[step].cover++;        return;    }    if(t[step].left==t[step].right) return;    int mid=(t[step].left+t[step].right)/2;    if(mid>=d) Insert(c,d,step*2);    else if(mid<c) Insert(c,d,step*2+1);    else    {        Insert(c,mid,step*2);        Insert(mid+1,d,step*2+1);    }}void Find(int c,int d,int step){    if (t[step].cover!=0)        sum=sum+t[step].cover*(d-c+1);    if (t[step].left==t[step].right)        return;    int mid=(t[step].left+t[step].right)>>1;    if (mid>=d)        Find(c,d,step*2);    else if(mid<c)        Find(c,d,step*2+1);    else    {        Find(c,mid,step*2);        Find(mid+1,d,step*2+1);    }}int main(){    cin>>n>>m;    build(0,n,1);    int l,r;    for(int i=0; i<m; i++)    {        cin>>l>>r;        Insert(l,r,1);    }    Find(4,4,1);    cout<<sum;    return 0;}

0 0