2019南昌网络赛 Yukino With Subinterval —— 树套树 或 cbq分治

题目链接:点我啊╭(╯^╰)╮
在这里插入图片描述
评测机好像换了,没有当初那么卡了。。。


      最快写法:

在这里插入图片描述

#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
//#pragma GCC optimize(3,"Ofast","inline")
using namespace std;
typedef long long ll;
using pii = pair <ll,int>;
const int maxn = 2e5 + 5;
int n, m, a[maxn], b[maxn], tot;
int t[maxn*210], ls[maxn*210], rs[maxn*210];
int T[maxn], tt[maxn], cnt;
namespace IO{
#define BUF_SIZE 100000
#define OUT_SIZE 100000
#define ll long long
    bool IOerror=0;
    inline char nc(){
        static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
        if (p1==pend){
            p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin);
            if (pend==p1){IOerror=1;return -1;}
        }
        return *p1++;
    }
    inline bool blank(char ch){return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';}
    inline void read(int &x){
        bool sign=0; char ch=nc(); x=0;
        for (;blank(ch);ch=nc());
        if (IOerror)return;
        if (ch=='-')sign=1,ch=nc();
        for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
        if (sign)x=-x;
    }
    inline void read(ll &x){
        bool sign=0; char ch=nc(); x=0;
        for (;blank(ch);ch=nc());
        if (IOerror)return;
        if (ch=='-')sign=1,ch=nc();
        for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
        if (sign)x=-x;
    }
    inline void read(double &x){
        bool sign=0; char ch=nc(); x=0;
        for (;blank(ch);ch=nc());
        if (IOerror)return;
        if (ch=='-')sign=1,ch=nc();
        for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
        if (ch=='.'){
            double tmp=1; ch=nc();
            for (;ch>='0'&&ch<='9';ch=nc())tmp/=10.0,x+=tmp*(ch-'0');
        }
        if (sign)x=-x;
    }
    inline void read(char *s){
        char ch=nc();
        for (;blank(ch);ch=nc());
        if (IOerror)return;
        for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
        *s=0;
    }
    inline void read(char &c){
        for (c=nc();blank(c);c=nc());
        if (IOerror){c=-1;return;}
    }
    //fwrite->write
    struct Ostream_fwrite{
        char *buf,*p1,*pend;
        Ostream_fwrite(){buf=new char[BUF_SIZE];p1=buf;pend=buf+BUF_SIZE;}
        void out(char ch){
            if (p1==pend){
                fwrite(buf,1,BUF_SIZE,stdout);p1=buf;
            }
            *p1++=ch;
        }
        void print(int x){
            static char s[15],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1);
        }
        void println(int x){
            static char s[15],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1); out('\n');
        }
        void print(ll x){
            static char s[25],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1);
        }
        void println(ll x){
            static char s[25],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1); out('\n');
        }
        void print(double x,int y){
            static ll mul[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,
                             1000000000,10000000000LL,100000000000LL,1000000000000LL,10000000000000LL,
                             100000000000000LL,1000000000000000LL,10000000000000000LL,100000000000000000LL};
            if (x<-1e-12)out('-'),x=-x;x*=mul[y];
            ll x1=(ll)floor(x); if (x-floor(x)>=0.5)++x1;
            ll x2=x1/mul[y],x3=x1-x2*mul[y]; print(x2);
            if (y>0){out('.'); for (size_t i=1;i<y&&x3*mul[i]<mul[y];out('0'),++i); print(x3);}
        }
        void println(double x,int y){print(x,y);out('\n');}
        void print(char *s){while (*s)out(*s++);}
        void println(char *s){while (*s)out(*s++);out('\n');}
        void flush(){if (p1!=buf){fwrite(buf,1,p1-buf,stdout);p1=buf;}}
        ~Ostream_fwrite(){flush();}
    }Ostream;
    inline void print(int x){Ostream.print(x);}
    inline void println(int x){Ostream.println(x);}
    inline void print(char x){Ostream.out(x);}
    inline void println(char x){Ostream.out(x);Ostream.out('\n');}
    inline void print(ll x){Ostream.print(x);}
    inline void println(ll x){Ostream.println(x);}
    inline void print(double x,int y){Ostream.print(x,y);}
    inline void println(double x,int y){Ostream.println(x,y);}
    inline void print(char *s){Ostream.print(s);}
    inline void println(char *s){Ostream.println(s);}
    inline void println(){Ostream.out('\n');}
    inline void flush(){Ostream.flush();}
#undef ll
#undef OUT_SIZE
#undef BUF_SIZE
};
using namespace IO;

inline int lowbit(int x){
	return x & (-x);
}

void update(int pos, int c, int l, int r){
	if(!pos || l>r) return;
	int tmp[25];
	for(int i=1; i<=cnt; i++) t[tt[i]] += c, tmp[i] = tt[i];
	if(l == r) return;
	int m = l + r >> 1;
	if(m >= pos) {
		for(int i=1; i<=cnt; i++){
			if(!ls[tmp[i]]) ls[tmp[i]] = ++tot;
			tt[i] = ls[tmp[i]];
		} 
		update(pos, c, l, m);
	}
	else {
		for(int i=1; i<=cnt; i++){
			if(!rs[tmp[i]]) rs[tmp[i]] = ++tot;
			tt[i] = rs[tmp[i]];
		} 
		update(pos, c, m+1, r);
	}
}

void add(int x, int v){
	cnt = 0;
	for(int i=x; i<=n; i+=lowbit(i)) 
		tt[++cnt] = T[i];
	update(a[x], v, 1, n);
}

int query(int l, int r, int L, int R){
	if(l>R || r<L) return 0;
	int tmp[25];
	int x = 0, m = l + r >> 1, ret = 0;
	for(int i=1; i<=cnt; ++i) x += t[tt[i]], tmp[i] = tt[i];
	if(L<=l && r<=R) return x;
	if(m >= L){
		for(int i=1; i<=cnt; ++i) tt[i] = ls[tmp[i]]; 
		ret += query(l, m, L, R);
	}
	if(R > m){
		for(int i=1; i<=cnt; ++i) tt[i] = rs[tmp[i]];
		ret += query(m+1, r, L, R); 
	}
	return ret;
}

int solve(int x, int l, int r){
	cnt = 0;
	for(int i=x; i; i-=lowbit(i)) 
		tt[++cnt] = T[i];
	return query(1, n, l, r);
}

int main() {
	read(n), read(m);
	for(int i=1; i<=n; i++) T[i] = ++tot;
	for(int i=1; i<=n; i++){
		read(a[i]);
		if(a[i] != a[i-1]) add(i, 1);
	}
	while(m--){
		int op, l, r, x, y;
		read(op);
		if(op & 1){
			read(l), read(r);
			if(a[l] == r) continue;
			if(a[l] != a[l-1]) add(l, -1);
			if (a[l] == a[l+1]) add(l+1, 1);
			else if(r == a[l+1]) add(l+1, -1);
			a[l] = r;
			if(a[l] != a[l-1]) add(l, 1);
		} else  {
			read(l), read(r), read(x), read(y);
			int ans = solve(r, x, y) - solve(l, x, y);
			int f = a[l]>=x && a[l]<=y;
			println(ans + f);
		}
	}
}

      旧写法:

在这里插入图片描述

#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
//#pragma GCC optimize(3,"Ofast","inline")
using namespace std;
typedef long long ll;
using pii = pair <ll,int>;
const int maxn = 2e5 + 5;
int n, m, a[maxn], b[maxn], tot;
int t[maxn*210], ls[maxn*210], rs[maxn*210];
int T[maxn], lt[maxn], rt[maxn], cnt1, cnt2;
namespace IO{
#define BUF_SIZE 100000
#define OUT_SIZE 100000
#define ll long long
    bool IOerror=0;
    inline char nc(){
        static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
        if (p1==pend){
            p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin);
            if (pend==p1){IOerror=1;return -1;}
        }
        return *p1++;
    }
    inline bool blank(char ch){return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';}
    inline void read(int &x){
        bool sign=0; char ch=nc(); x=0;
        for (;blank(ch);ch=nc());
        if (IOerror)return;
        if (ch=='-')sign=1,ch=nc();
        for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
        if (sign)x=-x;
    }
    inline void read(ll &x){
        bool sign=0; char ch=nc(); x=0;
        for (;blank(ch);ch=nc());
        if (IOerror)return;
        if (ch=='-')sign=1,ch=nc();
        for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
        if (sign)x=-x;
    }
    inline void read(double &x){
        bool sign=0; char ch=nc(); x=0;
        for (;blank(ch);ch=nc());
        if (IOerror)return;
        if (ch=='-')sign=1,ch=nc();
        for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
        if (ch=='.'){
            double tmp=1; ch=nc();
            for (;ch>='0'&&ch<='9';ch=nc())tmp/=10.0,x+=tmp*(ch-'0');
        }
        if (sign)x=-x;
    }
    inline void read(char *s){
        char ch=nc();
        for (;blank(ch);ch=nc());
        if (IOerror)return;
        for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
        *s=0;
    }
    inline void read(char &c){
        for (c=nc();blank(c);c=nc());
        if (IOerror){c=-1;return;}
    }
    //fwrite->write
    struct Ostream_fwrite{
        char *buf,*p1,*pend;
        Ostream_fwrite(){buf=new char[BUF_SIZE];p1=buf;pend=buf+BUF_SIZE;}
        void out(char ch){
            if (p1==pend){
                fwrite(buf,1,BUF_SIZE,stdout);p1=buf;
            }
            *p1++=ch;
        }
        void print(int x){
            static char s[15],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1);
        }
        void println(int x){
            static char s[15],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1); out('\n');
        }
        void print(ll x){
            static char s[25],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1);
        }
        void println(ll x){
            static char s[25],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1); out('\n');
        }
        void print(double x,int y){
            static ll mul[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,
                             1000000000,10000000000LL,100000000000LL,1000000000000LL,10000000000000LL,
                             100000000000000LL,1000000000000000LL,10000000000000000LL,100000000000000000LL};
            if (x<-1e-12)out('-'),x=-x;x*=mul[y];
            ll x1=(ll)floor(x); if (x-floor(x)>=0.5)++x1;
            ll x2=x1/mul[y],x3=x1-x2*mul[y]; print(x2);
            if (y>0){out('.'); for (size_t i=1;i<y&&x3*mul[i]<mul[y];out('0'),++i); print(x3);}
        }
        void println(double x,int y){print(x,y);out('\n');}
        void print(char *s){while (*s)out(*s++);}
        void println(char *s){while (*s)out(*s++);out('\n');}
        void flush(){if (p1!=buf){fwrite(buf,1,p1-buf,stdout);p1=buf;}}
        ~Ostream_fwrite(){flush();}
    }Ostream;
    inline void print(int x){Ostream.print(x);}
    inline void println(int x){Ostream.println(x);}
    inline void print(char x){Ostream.out(x);}
    inline void println(char x){Ostream.out(x);Ostream.out('\n');}
    inline void print(ll x){Ostream.print(x);}
    inline void println(ll x){Ostream.println(x);}
    inline void print(double x,int y){Ostream.print(x,y);}
    inline void println(double x,int y){Ostream.println(x,y);}
    inline void print(char *s){Ostream.print(s);}
    inline void println(char *s){Ostream.println(s);}
    inline void println(){Ostream.out('\n');}
    inline void flush(){Ostream.flush();}
#undef ll
#undef OUT_SIZE
#undef BUF_SIZE
};
using namespace IO;

inline int lowbit(int x){
	return x & (-x);
}

void update(int &rt, int pos, int c, int l, int r){
	if(!pos || l>r) return;
	if(!rt) rt = ++tot;
	t[rt] += c;
	if(l == r) return;
	int m = l + r >> 1;
	if(m >= pos) update(ls[rt], pos, c, l, m);
	else update(rs[rt], pos, c, m+1, r);
}

void add(int x, int v){
	for(int i=x; i<=n; i+=lowbit(i))	
		update(T[i], a[x], v, 1, n);
}

int query(int l, int r, int L, int R){
	if(l>R || r<L) return 0;
	int tmpl[25], tmpr[25];
	int x = 0, m = l + r >> 1, ret = 0;
	for(int i=1; i<=cnt1; ++i) x -= t[lt[i]], tmpl[i] = lt[i];
	for(int i=1; i<=cnt2; ++i) x += t[rt[i]], tmpr[i] = rt[i];
	if(L<=l && r<=R) return x;
	if(m >= L){
		for(int i=1; i<=cnt1; ++i) lt[i] = ls[tmpl[i]];
		for(int i=1; i<=cnt2; ++i) rt[i] = ls[tmpr[i]]; 
		ret += query(l, m, L, R);
	}
	if(R > m){
		for(int i=1; i<=cnt1; ++i) lt[i] = rs[tmpl[i]];
		for(int i=1; i<=cnt2; ++i) rt[i] = rs[tmpr[i]];
		ret += query(m+1, r, L, R); 
	}
	return ret;
}

int main() {
	read(n), read(m);
	for(int i=1; i<=n; i++){
		read(a[i]);
		if(a[i] != a[i-1]) add(i, 1);
	}
	while(m--){
		int op, l, r, x, y;
		read(op);
		if(op & 1){
			read(l), read(r);
			if(a[l] == r) continue;
			if(a[l] != a[l-1]) add(l, -1);
			if (a[l] == a[l+1]) add(l+1, 1);
			else if(r == a[l+1]) add(l+1, -1);
			a[l] = r;
			if(a[l] != a[l-1]) add(l, 1);
		} else  {
			cnt1 = cnt2 = 0;
			read(l), read(r), read(x), read(y);
			for(int i=l; i; i-=lowbit(i)) lt[++cnt1] = T[i];
			for(int i=r; i; i-=lowbit(i)) rt[++cnt2] = T[i];
			int f = a[l]>=x && a[l]<=y;
			println(query(1, n, x, y) + f);
		}
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值