zoukankan      html  css  js  c++  java
  • HDU6989 Didn't I Say to Make My Abilities Average in the Next Life?!

    传送门


    这题比赛的时候虽然做的人相对较多,但是自己根本没有什么头绪。


    一句话题意:(n)个数,(m)个询问,每次让你求

    $sumlimits_{L leqslant i leqslant j leqslant R}frac{ extrm{min}_{i cdots j} + extrm{max}_{i cdots j}}{2} / frac{len * (len + 1)}{2} extrm{mod} 10^9+7$.

    题解给了个线段树的乱七八糟的十分复杂的算法,没看懂。顾子哥给我推荐了一道几乎一模一样的题,洛谷上第一篇题解妙的很,所以直接看我的这篇题解吧。


    那这道题就是要分别求一遍最大值和最小值罢了。

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<vector>
    #include<queue>
    #include<assert.h>
    #include<ctime>
    using namespace std;
    #define enter puts("") 
    #define space putchar(' ')
    #define Mem(a, x) memset(a, x, sizeof(a))
    #define In inline
    #define forE(i, x, y) for(int i = head[x], y; ~i && (y = e[i].to); i = e[i].nxt)
    typedef long long ll;
    typedef double db;
    const int INF = 0x3f3f3f3f;
    const db eps = 1e-8;
    const int maxn = 2e5 + 5;
    const int N = 18;
    const ll mod = 1e9 + 7;
    In ll read()
    {
    	ll ans = 0;
    	char ch = getchar(), las = ' ';
    	while(!isdigit(ch)) las = ch, ch = getchar();
    	while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
    	if(las == '-') ans = -ans;
    	return ans;
    }
    In void write(ll x)
    {
    	if(x < 0) x = -x, putchar('-');
    	if(x >= 10) write(x / 10);
    	putchar(x % 10 + '0');
    }
    In void MYFILE()
    {
    #ifndef mrclr
    	freopen("1005.in", "r", stdin);
    	freopen("ha.out", "w", stdout);
    #endif
    }
    
    In ll ADD(ll a, ll b) {return a + b < mod ? a + b : a + b - mod;}
    In ll quickpow(ll a, ll b)
    {
    	ll ret = 1;
    	for(; b; b >>= 1, a = a * a % mod)
    		if(b & 1) ret = ret * a % mod;
    	return ret;
    }
    
    int n, m, a[maxn];
    
    struct Node
    {
    	ll f[maxn], sum[maxn];
    }MIN[2], MAX[2];
    int st[maxn], top = 0, pre[maxn];
    In void calc(Node& A, int flg)
    {
    	top = 0;
    	for(int i = n; i; --i)
    	{
    		while(top && a[i] <= a[st[top]]) pre[st[top--]] = i;
    		st[++top] = i;
    	}
    	while(top) pre[st[top--]] = 0;
    	for(int i = 1; i <= n; ++i) A.f[i] = ADD(A.f[pre[i]], 1LL * flg * a[i] * (i - pre[i]) % mod);
    	for(int i = 1; i <= n; ++i) A.sum[i] = ADD(A.sum[i - 1], A.f[i]);	
    }
    int dp[maxn][N + 2][2], ha[maxn];
    In void rmq_init()
    {
    	for(int i = 1; i <= n; ++i) dp[i][0][0] = dp[i][0][1] = i;
    	for(int j = 1; (1 << j) <= n; ++j)
    		for(int i = 1; i + (1 << j) - 1 <= n; ++i)
    		{
    			int tp1 = dp[i][j - 1][0], tp2 = dp[i + (1 << (j - 1))][j - 1][0];
    			dp[i][j][0] = a[tp1] < a[tp2] ? tp1 : tp2;
    			tp1 = dp[i][j - 1][1], tp2 = dp[i + (1 << (j - 1))][j - 1][1];
    			dp[i][j][1] = a[tp1] > a[tp2] ? tp1 : tp2;			
    		}
    	for(int i = 2; i <= n; ++i) ha[i] = ha[i >> 1] + 1;
    }
    #define pr pair<int, int>
    #define F first
    #define S second
    In pr query(int L, int R)
    {
    	int k = ha[R - L + 1];
    	int tp1 = dp[L][k][0], tp2 = dp[R - (1 << k) + 1][k][0];
    	int ret1 = a[tp1] < a[tp2] ? tp1 : tp2;
    	tp1 = dp[L][k][1], tp2 = dp[R - (1 << k) + 1][k][1];
    	int ret2 = a[tp1] > a[tp2] ? tp1 : tp2;	
    	return make_pair(ret1, ret2);
    }
    
    In void solve()
    {
    	calc(MIN[0], 1);
    	reverse(a + 1, a + n + 1);
    	calc(MIN[1], 1);
    	reverse(MIN[1].f + 1, MIN[1].f + n + 1);
    	reverse(MIN[1].sum + 1, MIN[1].sum + n + 1);
    	reverse(a + 1, a + n + 1);
    	for(int i = 1; i <= n; ++i) a[i] = -a[i];
    	calc(MAX[0], -1);
    	reverse(a + 1, a + n + 1);
    	calc(MAX[1], -1);
    	reverse(MAX[1].f + 1, MAX[1].f + n + 1);
    	reverse(MAX[1].sum + 1, MAX[1].sum + n + 1);
    	reverse(a + 1, a + n + 1);
    	for(int i = 1; i <= n; ++i) a[i] = -a[i];
    	rmq_init();
    	
    	for(int i = 1; i <= m; ++i)
    	{
    		int L = read(), R = read(), len = R - L + 1;
    		pr tp = query(L, R); int p1 = tp.F, p2 = tp.S;
    		ll ans1 = MIN[0].sum[R] - MIN[0].sum[p1] - MIN[0].f[p1] * (R - p1) % mod;
    		ans1 = ADD(ans1 % mod, mod);
    		ll ans2 = MIN[1].sum[L] - MIN[1].sum[p1] - MIN[1].f[p1] * (p1 - L) % mod;
    		ans2 = ADD(ans2 % mod, mod);
    		ll ANS1 = ADD(1LL * a[p1] * (R - p1 + 1) % mod * (p1 - L + 1) % mod, ADD(ans1, ans2));
    		ans1 = MAX[0].sum[R] - MAX[0].sum[p2] - MAX[0].f[p2] * (R - p2) % mod;
    		ans1 = ADD(ans1 % mod, mod);
    		ans2 = MAX[1].sum[L] - MAX[1].sum[p2] - MAX[1].f[p2] * (p2 - L) % mod;
    		ans2 = ADD(ans2 % mod, mod);
    		ll ANS2 = ADD(1LL * a[p2] * (R - p2 + 1) % mod * (p2 - L + 1) % mod, ADD(ans1, ans2));
    		write(ADD(ANS1, ANS2) * quickpow(1LL * len * (len + 1) % mod, mod - 2) % mod), enter; 
    	}
    }
    
    int main()
    {
    //	MYFILE();
    	int T = read();
    	while(T--)
    	{
    		n = read(), m = read();
    		for(int i = 1; i <= n; ++i) a[i] = read();
    		solve();
    	}
    	return 0;
    }
    
  • 相关阅读:
    evernote100个做笔记的好方法
    平衡二叉树的调整模版
    晨间日记的奇迹
    hdu 2952 Counting Sheep
    hdu 1535 Invitation Cards
    poj 3259 Wormholes(spfa)
    poj 2263 Heavy Cargo(floyd)
    poj 3268 Silver Cow Party(SPFA)
    hdu 1690 Bus System
    hdu 3631 Shortest Path(Floyd)
  • 原文地址:https://www.cnblogs.com/mrclr/p/15083830.html
Copyright © 2011-2022 走看看