信心 - 平衡树 - 树状数组

题目大意:维护n个集合(不可重),每次区间insert一个数字x或者求区间集合大小之和。
题解:对每个x维护一个set表示当前那些段是空的即可。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define ull unsigned lint
#define db long double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
namespace INPUT_SPACE{
    const int BS=(1<<24)+5;char Buffer[BS],*HD,*TL;
    char gc() { if(HD==TL) TL=(HD=Buffer)+fread(Buffer,1,BS,stdin);return (HD==TL)?EOF:*HD++; }
    inline int inn()
    {
        int x,ch;while((ch=gc())<'0'||ch>'9');
        x=ch^'0';while((ch=gc())>='0'&&ch<='9')
            x=(x<<1)+(x<<3)+(ch^'0');return x;
    }
}using INPUT_SPACE::inn;
namespace OUTPUT_SPACE{
    char ss[2000000],tt[20];int ssl,ttl;
    inline int PC(char c) { return ss[++ssl]=c; }
    inline int print(lint x)
    {
        if(!x) ss[++ssl]='0';
        for(ttl=0;x;x/=10) tt[++ttl]=char(x%10+'0');
        for(;ttl;ttl--) ss[++ssl]=tt[ttl];return 0;
    }
    inline int Flush() { return fwrite(ss+1,sizeof(char),ssl,stdout),0; }
}using OUTPUT_SPACE::print;using OUTPUT_SPACE::PC;using OUTPUT_SPACE::Flush;
const int N=100010,V=100010;
typedef set<pii>::iterator spiit;
set<pii> s[V];
#define lb(x) ((x)&-(x))
struct BIT{
    lint b[N];lint r[N];int n;
    inline int init(int _n) { return n=_n,memset(b,0,sizeof(int)*(n+1)),memset(r,0,sizeof(lint)*(n+1)),0; }
    inline int update(int s,int t)
    {
        for(int x=s;x<=n;x+=lb(x)) b[x]++;
        for(int x=s;x<=n;x+=lb(x)) r[x]+=s;
        for(int x=t+1;x<=n;x+=lb(x)) b[x]--;
        for(int x=t+1;x<=n;x+=lb(x)) r[x]-=t+1;
        return 0;
    }
    inline lint query(int s,int t) { return query(t)-query(s-1); }
    inline lint query(int n)
    {
        lint bs=0;lint rs=0;
        for(int x=n;x;x-=lb(x)) bs+=b[x],rs+=r[x];
        return bs*(n+1ll)-rs;
    }
}b;
inline spiit qry(set<pii> &s,int x) { return s.lower_bound(mp(x,0)); }
inline int upd(int l,int r,set<pii> &s)
{
    spiit it=qry(s,l);
    if(it!=s.begin())
    {
        spiit las=it;las--;
        if(l<=las->sec)
        {
            if(las->sec<=r)
                s.insert(mp(las->fir,l-1)),
                b.update(l,las->sec),s.erase(las);
            else
                s.insert(mp(las->fir,l-1)),
                s.insert(mp(r+1,las->sec)),
                b.update(l,r),s.erase(las);
        }
    }
    for(it=qry(s,l);it!=s.end()&&it->sec<=r;it=qry(s,l))
        b.update(it->fir,it->sec),s.erase(it);
    it=qry(s,l);
    if(it!=s.end()&&it->fir<=r)
        s.insert(mp(r+1,it->sec)),b.update(it->fir,r),s.erase(it);
    return 0;
}
int main()
{
    int n=inn(),q=inn();b.init(n);
    rep(i,1,n) s[i].insert(mp(1,n));
    while(q--)
    {
        int tp=inn(),l=inn(),r=inn();
        if(!tp) upd(l,r,s[inn()]);
        else printf("%lld\n",b.query(l,r));
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Mys_C_K/article/details/84817722
今日推荐