分治的一道题

来源:互联网 发布:知乎宇宙高维 编辑:程序博客网 时间:2024/05/20 07:51

数据范围 n <= 5e5

分治:

/************************************************************************* > Author: wzw-cnyali > Created Time: 2017/9/11 18:44:56 ************************************************************************/#include<iostream>#include<cstdio>#include<cstdlib>#include<cmath>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;#define REP(i, a, b) for(register int i = (a), i##_end_ = (b); i <= i##_end_; ++ i)#define DREP(i, a, b) for(register int i = (a), i##_end_ = (b); i >= i##_end_; -- i)#define EREP(i, a) for(register int i = (be[a]); i != -1; i = nxt[i])#define mem(a, b) memset((a), b, sizeof(a))template<typename T> inline bool chkmin(T &a, const T &b) { return a > b ? a = b, 1 : 0; }template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }char buff[1 << 25], *buf = buff;template <class T>T read(T sum = 0, T fg = 0){while(*buf < '0' || *buf > '9') { fg |= *buf == '-'; buf++; }while(*buf >= '0' && *buf <= '9') { sum = sum * 10 + *buf - '0'; buf++; }return fg ? -sum : sum;}const LL INF = 1e14;const int Size = 500010;const LL mod = 1e9 + 7;int n;LL a[Size];LL mx, mn, ans;LL smax[Size], smin[Size], sum[Size];void solve(int L, int R){if(L == R){(ans += (a[L] * a[L]) % mod) %= mod;return;}LL mid = L + R >> 1;solve(L, mid); solve(mid + 1, R);mx = -INF, mn = INF;REP(i, mid + 1, R){chkmax(mx, a[i]); chkmin(mn, a[i]);smax[i] = (smax[i - 1] + mx) % mod;smin[i] = (smin[i - 1] + mn) % mod;sum[i] = (sum[i - 1] + (mx * mn) % mod) % mod;}mx = -INF, mn = INF;LL rmx = mid + 1, rmn = mid + 1;DREP(i, mid, L){chkmax(mx, a[i]); chkmin(mn, a[i]);for(; rmx <= R && a[rmx] <= mx; ++rmx);for(; rmn <= R && a[rmn] >= mn; ++rmn);LL r1 = min(rmx, rmn), r2 = max(rmx, rmn);(ans += ((mx * mn) % mod * (r1 - mid - 1)) % mod) %= mod;(ans += (sum[R] - sum[r2 - 1] + mod) % mod) %= mod;if(rmx <= rmn) (ans += (mn * (smax[r2 - 1] - smax[r1 - 1])) % mod) %= mod;else (ans += (mx * (smin[r2 - 1] - smin[r1 - 1])) % mod) %= mod;}}int main(){#ifndef ONLINE_JUDGEfreopen("input.in", "r", stdin);freopen("output.out", "w", stdout);#endiffread(buff, 1, 1 << 25, stdin);n = read<int>();REP(i, 1, n) a[i] = read<int>();solve(1, n);printf("%lld\n", (ans + mod) % mod);return 0;}


原创粉丝点击