1-n建一颗线段树,然后保存区间元素个数和区间元素最大值。。。
#include <iostream> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits> #include <cstdlib> #include <cmath> #include <time.h> #define maxn 50005 #define maxm 40005 #define eps 1e-10 #define mod 998244353 #define INF 999999999 #define lowbit(x) (x&(-x)) #define mp mark_pair #define ls o<<1 #define rs o<<1 | 1 #define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R typedef long long LL; //typedef int LL; using namespace std; LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;} void scanf(int &__x){__x=0;char __ch=getchar();while(__ch==' '||__ch=='\n')__ch=getchar();while(__ch>='0'&&__ch<='9')__x=__x*10+__ch-'0',__ch = getchar();} // head LL maxv[maxn<<2], sum[maxn<<2]; LL mark[maxn<<2]; char ss[maxn]; int n, m; void pushup(int o) { sum[o] = sum[ls] + sum[rs]; maxv[o] = max(maxv[ls], maxv[rs]); } void pushdown(int o) { if(mark[o]) { LL tmp = powmod(2, mark[o]); sum[ls] *= tmp; sum[rs] *= tmp; maxv[ls] *= tmp; maxv[rs] *= tmp; mark[ls] += mark[o]; mark[rs] += mark[o]; mark[o] = 0; } } void build(int o, int L, int R) { if(L == R) { sum[o] = maxv[o] = 1; mark[o] = 0; return; } mark[o] = 0; int mid = (L+R)>>1; build(lson); build(rson); pushup(o); } void updata(int o, int L, int R, LL ql, LL qr) { if(L == R) { sum[o] += qr - ql + 1; maxv[o] = sum[o]; return; } if(sum[o] == qr - ql + 1) { sum[o] *= 2; maxv[o] *= 2; mark[o]++; return; } pushdown(o); int mid = (L+R)>>1; LL tmp = sum[ls]; if(tmp >= ql) updata(lson, ql, min(qr, tmp)); if(tmp < qr) updata(rson, max(tmp+1, ql)-tmp, qr-tmp); pushup(o); } LL query(int o, int L, int R, LL ql, LL qr) { if(L == R) return qr - ql + 1; if(sum[o] == qr - ql + 1) return maxv[o]; pushdown(o); int mid = (L+R)>>1; LL ans = 0; if(sum[ls] >= ql) ans = max(ans, query(lson, ql, min(qr, sum[ls]))); if(sum[ls] < qr) ans = max(ans, query(rson, max(sum[ls]+1, ql)-sum[ls], qr-sum[ls])); pushup(o); return ans; } void work(void) { LL ql, qr; while(m--) { scanf("%s", ss); scanf("%I64d%I64d", &ql, &qr); if(ss[0] == 'D') updata(1, 1, n, ql, qr); else printf("%I64d\n", query(1, 1, n, ql, qr)); } } int main(void) { int _, __; while(scanf("%d", &_)!=EOF) { __ = 0; while(_--) { scanf("%d%d", &n, &m); build(1, 1, n); printf("Case #%d:\n", ++__); work(); } } return 0; }