luogu P1047 校门外的树(我只会做这个难度的题啦p_q

传送门

代码:

#include<bits/stdc++.h>
using namespace std;
#define maxn 1000000
int n,m,x,y,z,ans;

struct TreeType{
    int l,r,f,w;
}tree[maxn<<2];

void tree_up(int k) { tree[k].w=tree[k<<1|1].w+tree[k<<1].w; }

void tree_down(int k)
{
    tree[k<<1].f+=tree[k].f;
    tree[k<<1|1].f+=tree[k].f;
    tree[k<<1].w+=(tree[k<<1].r-tree[k<<1].l+1)*tree[k<<1].f;
    tree[k<<1|1].w+=(tree[k<<1|1].r-tree[k<<1|1].l+1)*tree[k<<1|1].f;
    tree[k].f=0; 
}

void tree_build(int l,int r,int k)
{
    tree[k].l=l; tree[k].r=r;
    if(l==r)
    {
        tree[k].w=1;
        return ;
    }
    int mid=(tree[k].l+tree[k].r)>>1;
    tree_build(l,mid,k<<1);
    tree_build(mid+1,r,k<<1|1);
    tree_up(k);
}

void tree_change(int l,int r,int k,int x)
{
    if(tree[k].l==l&&tree[k].r==r)
    {
        tree[k].w+=(tree[k].r-tree[k].l+1)*x;
        tree[k].f+=x;
        tree_down(k);
        return ;
     }
    if(tree[k].f) tree_down(k);
    int mid=(tree[k].l+tree[k].r)>>1;
    if(l>mid)  tree_change(l,r,k<<1|1,x);
    else if(r<=mid) tree_change(l,r,k<<1,x);
    else {
        tree_change(l,mid,k<<1,x);
        tree_change(mid+1,r,k<<1|1,x);
    }
}

int tree_find(int k,int to)
{

    if(tree[k].l==tree[k].r)    return tree[k].w;
    if(tree[k].f) tree_down(k);
    int mid=(tree[k].r+tree[k].l)/2;
    if(to>mid) return tree_find(k*2+1,to);
    else return tree_find(k*2,to);
}

int main()
{
    scanf("%d%d",&n,&m);
    tree_build(0,n,1);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        tree_change(x,y,1,-1);
    }
    for(int i=0;i<=n;i++)
        if(tree_find(1,i)>0) ans++;
    cout<<ans;
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/chen74123/p/7350466.html