線段樹

單點更新

/*
* @Author: qin_peng
* @Date:   2018-08-20 23:22:08
* @Last Modified by:   qin_peng
* @Last Modified time: 2018-08-29 23:22:34
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=55555;
int sum[maxn<<2]={0};
void pushup(int rt){sum[rt]=sum[rt<<1]+sum[rt<<1|1];}
void build(int l,int r,int rt)
{
    if(l==r){scanf("%d",&sum[rt]);return ;}
    int m=(l+r)>>1;
    build(lson),build(rson);
    pushup(rt);
}
void update(int pos,int val,int l,int r,int rt)
{
    if(l==r)
    {
        sum[rt]+=val;return ;
    }
    int m=(l+r)>>1;
    if(pos<=m)update(pos,val,lson);
    else update(pos,val,rson);pushup(rt);
}
int query(int L,int R,int l,int r,int rt)
{
    if(L<=l and r<=R)return sum[rt]; 
    int m=(l+r)>>1;
    int res=0;
    if(L<=m)res+=query(L,R,lson); 
    if(R>m)res+=query(L,R,rson);
    return res;
}

區間更新

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=200005;
ll sum[maxn<<2|1]={0};
ll add[maxn<<2|1]={0};
void pushup(int rt){sum[rt]=sum[rt<<1]+sum[rt<<1|1];}
void pushdown(int rt,int m)
{
    if(add[rt])
    {
        add[rt<<1]+=add[rt];
        add[rt<<1|1]+=add[rt];
        sum[rt<<1]+=add[rt]*(m-(m>>1));
        sum[rt<<1|1]+=add[rt]*(m>>1);
        add[rt]=0;
    }
}
void build(int l,int r,int rt)
{
    if(l==r){scanf("%lld",&sum[rt]);return;}
    int m=(l+r)>>1;
    build(lson),build(rson);
    pushup(rt);
}
void update(int L,int R,int val,int l,int r,int rt)
{
    if(l>=L and r<=R)
    {
        add[rt]+=val;
        sum[rt]+=(ll)val*(r-l+1);return ;
    }
    pushdown(rt,r-l+1);
    int m=(l+r)>>1;
    if(L<=m)update(L,R,val,lson);
    if(m<R)update(L,R,val,rson);
    pushup(rt);
}
ll query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&R>=r)return sum[rt];
    pushdown(rt,r-l+1);
    int m=(l+r)>>1;
    ll res=0;
    if(m>=L)res+=query(L,R,lson);
    if(m<R)res+=query(L,R,rson);
    return res;
}

區間合併

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define root 1,n,1
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int N=5e4+10;
int lsum[N<<2],rsum[N<<2],head[N],n,q;
void push_up(int rt,int m)
{
    lsum[rt]=lsum[rt<<1];
    rsum[rt]=rsum[rt<<1|1];
    if(lsum[rt<<1]==m-(m>>1))lsum[rt]+=lsum[rt<<1|1];
    if(rsum[rt<<1|1]==m>>1)rsum[rt]+=rsum[rt<<1];
}
void build(int l,int r,int rt)
{
    lsum[rt]=rsum[rt]=r-l+1;
    if(l==r)return ;
    int m=l+r>>1;
    build(lson),build(rson);
}
void update(int p,int val,int l,int r,int rt)
{
    if(l==r){lsum[rt]=rsum[rt]=val;return;}
    int m=l+r>>1;
    if(p<=m)update(p,val,lson);
    else update(p,val,rson);
    push_up(rt,r-l+1);
}
int query(int p,int l,int r,int rt)
{
    if(l==r)return 0;
    int m=l+r >>1;
    if(p>=m-rsum[rt<<1]+1&&p<=m+lsum[rt<<1|1])
    return rsum[rt<<1]+lsum[rt<<1|1];
    if(p<=m) return query(p,lson);
    else return query(p,rson);
}

經典染色

#include<cstring>  
#include<algorithm>  
#include<cstdio>  
#include<cmath>  
#include<queue>  
#define MAXN 40010  
#define inf 0x3f3f3f3f  
using namespace std;  
int li[MAXN];
int ri[MAXN];
int lisan[MAXN<<2];
int tree[MAXN<<2]; 
int vis[MAXN<<2];
int ans;
void pushdown(int p)
{
    tree[p<<1]=tree[(p<<1)|1]=tree[p];
    tree[p]=-1;
}
void update(int p,int l,int r,int x,int y,int a)
{
    if(x<=l&&y>=r)
    {
        tree[p]=a;
        return ;
    }
    if(tree[p]!=-1)
    pushdown(p);
    int mid=(l+r)>>1;   if(y<=mid)
    update(p<<1,l,mid,x,y,a);
    else if(x>mid)
    update((p<<1)|1,mid+1,r,x,y,a);
    else
    {
        update(p<<1,l,mid,x,mid,a);
        update((p<<1)|1,mid+1,r,mid+1,y,a);
    }
}
void query(int p,int l,int r)
{
    if(l==r)
    {
        if(!vis[tree[p]]&&tree[p]!=-1)
        {
           ans++;
           vis[tree[p]]=1;
        }
        return ;
    }
    if(tree[p]!=-1)
    pushdown(p);
    int mid=(l+r)>>1;
    query(p<<1,l,mid);
    query((p<<1)|1,mid+1,r);
}
int main()  
{  
    int t;
    scanf("%d",&t);
    int n;
    while(t--)
    {
        scanf("%d",&n);
        memset(tree,-1,sizeof(tree));
        memset(vis,0,sizeof(vis));
        int tot=0;
        for(int i=0;i<n;i++)
        {
            scanf("%d%d",&li[i],&ri[i]);
            lisan[tot++]=li[i];
            lisan[tot++]=ri[i];
        }
        sort(lisan,lisan+tot);
        int m=unique(lisan,lisan+tot)-lisan;
        int tem=m;
        for(int i=1;i<tem;i++)
        {
            if(lisan[i]-lisan[i-1]>1)
            {
                lisan[m++]=lisan[i-1]+1;
            }
        }
        sort(lisan,lisan+m);
        for(int i=0;i<n;i++)
        {
            int x=lower_bound(lisan,lisan+m,li[i])-lisan;
            int y=lower_bound(lisan,lisan+m,ri[i])-lisan;
            update(1,0,m-1,x,y,i);
        }
        ans=0;
        query(1,0,m-1);
        printf("%d\n",ans);
    }
    return 0;  
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章