这真是一道好题啊……
看起来觉得似曾相识,但就是想不出来区间怎么合并,最后还是听lbg巨佬讲的……
<高能算法>
连线段树都不用,树状数组就行了。
对于修改区间[L, R],分别用树状数组cl, cr维护L和R的前缀和。统计的时候就是cl(R) - cr(L - 1)!理解起来就是先找出所有在R之前被修改的区间,然后在减去L之前就结束的区间就行啦!
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<vector> 9 #include<stack> 10 #include<queue> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(' ') 14 #define Mem(a, x) memset(a, x, sizeof(a)) 15 #define rg register 16 typedef long long ll; 17 typedef double db; 18 const int INF = 0x3f3f3f3f; 19 const db eps = 1e-8; 20 const int maxn = 1e5 + 5; 21 const ll mod = 1e9 + 7; 22 inline ll read() 23 { 24 ll ans = 0; 25 char ch = getchar(), last = ' '; 26 while(!isdigit(ch)) {last = ch; ch = getchar();} 27 while(isdigit(ch)) {ans = (ans << 1) + (ans << 3) + ch - '0'; ch = getchar();} 28 if(last == '-') ans = -ans; 29 return ans; 30 } 31 inline void write(ll x) 32 { 33 if(x < 0) x = -x, putchar('-'); 34 if(x >= 10) write(x / 10); 35 putchar(x % 10 + '0'); 36 } 37 38 int n, m; 39 40 int cs[maxn], ce[maxn]; 41 int lowbit(int x) 42 { 43 return x & -x; 44 } 45 void add_s(int pos) 46 { 47 for(; pos <= n; pos += lowbit(pos)) cs[pos]++; 48 } 49 void add_e(int pos) 50 { 51 for(; pos <= n; pos += lowbit(pos)) ce[pos]++; 52 } 53 int sum_s(int pos) 54 { 55 int ret = 0; 56 for(; pos; pos -= lowbit(pos)) ret += cs[pos]; 57 return ret; 58 } 59 int sum_e(int pos) 60 { 61 int ret = 0; 62 for(; pos; pos -= lowbit(pos)) ret += ce[pos]; 63 return ret; 64 } 65 66 int main() 67 { 68 n = read(); m = read(); 69 for(int i = 1; i <= m; ++i) 70 { 71 int d = read(), L = read(), R = read(); 72 if(d == 1) add_s(L), add_e(R); 73 else 74 { 75 if(L > 1) write(sum_s(R) - sum_e(L - 1)), enter; 76 else write(sum_s(R)), enter; 77 } 78 } 79 return 0; 80 }