1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| #include <cstdio> #include <cmath>
inline int max(const int x, const int y) {return x > y ? x : y;} inline int min(const int x, const int y) {return x < y ? x : y;} inline void max2(int& x, const int y) {if (x < y) x = y;}
namespace GenHelper { unsigned z1,z2,z3,z4,b; unsigned rand_() { b=((z1<<6)^z1)>>13; z1=((z1&4294967294U)<<18)^b; b=((z2<<2)^z2)>>27; z2=((z2&4294967288U)<<2)^b; b=((z3<<13)^z3)>>21; z3=((z3&4294967280U)<<7)^b; b=((z4<<3)^z4)>>12; z4=((z4&4294967168U)<<13)^b; return (z1^z2^z3^z4); } } void srand(unsigned x) {using namespace GenHelper; z1=x; z2=(~x)^0x233333333U; z3=x^0x1234598766U; z4=(~x)+51;} int read() { using namespace GenHelper; int a=rand_()&32767; int b=rand_()&32767; return a*32768+b; }
int a[20000005], b[5005], c[20000005], d[20000005], s[5005], st[5005][15], S; inline int Query(const int L, const int R) { int k(log2(R - L + 1)); return max(st[L][k], st[R - (1 << k) + 1][k]); } inline int query(const int l, const int r) { int i((l - 1) / S + 1), j((r - 1) / S + 1), ans(0); if (i == j) { for (int k(l); k <= r; ++ k) ans = max(ans, a[k]); return ans; } if (i + 1 < j) ans = Query(i + 1, j - 1); return max(ans, max(d[l], c[r])); }
int main() { int n, m, s; unsigned long long ans(0); scanf("%d%d%d", &n, &m, &s); S = sqrt(n); srand(s); int len(ceil(n * 1.0 / S)); for (int i(1); i <= n; ++ i) max2(b[(i - 1) / S + 1], a[i] = read()); for (int i(1); i <= len; ++ i) { int st((i - 1) * S + 1), ed(min(n, i * S)); c[st] = a[st]; for (int j(st + 1); j <= ed; ++ j) c[j] = max(c[j - 1], a[j]); d[ed] = a[ed]; for (int j(ed - 1); j >= st; -- j) d[j] = max(d[j + 1], a[j]); } for (int i(1); i <= len; ++ i) st[i][0] = b[i]; for (int j(1); 1 << j <= len; ++ j) for (int i(1); i + (1 << j) - 1 <= len; ++ i) st[i][j] = max(st[i][j - 1], st[i + (1 << j - 1)][j - 1]); while (m --) { int l, r; l = read() % n + 1, r = read() % n + 1; if (l > r) l ^= r ^= l ^= r; ans += query(l, r); } printf("%llu", ans); return 0; }
|