codeforces 817D Imbalanced Array
来源:互联网 发布:蓝月传奇附灵数据 编辑:程序博客网 时间:2024/06/06 08:58
传送门
借用大犇的想法。
题意:
给出一组数,求所有连续子串的最大值与最小值差的和
题解:
从每个数可作为最大值被计算次数Maxki和最小值计算次数Minki入手,答案就是sum(Maxki*num[i]-Minki*num[i])
那么如何计算Maxki和Minki呢?
首先假设这个数num[i]是连续子串的第一位数,那么我们向右查询到第一个大于等于它的数的下标为Maxridx,则以这个数为第一位数的连续子串中这个数作为最大值被计算了Maxridx-i+1次,同样作为最小值可以采取同样的方法这个数被计算了Minridx-i+1次。这里的查找可以采用二分+RMQ因为最大值和最小值都有单调性。
接下来再从这个数不是连续子串的第一位开始考虑:
因为第i个数前面也可能存在比它大的数,所以可以从第i个数向左查找到第一个大于等于它的数的下标Maxlidx,则这个数作为最大值被计算了(i-Maxlidx+1)*(Maxridx-i+1)次,
作为最小值被计算了(i-Minlidx+1)*(Minridx-i+1)次。这个向左查找最值的方法采用单调栈的方法。
所以最后第i个数对答案的贡献为(i-Maxlidx+1)*(Maxridx-i+1)*num[i]-(i-Minlidx+1)*(Minridx-i+1)*num[i]
#include <iostream>#include <stdio.h>#include <cstring>#include <string>#include <algorithm>#include <queue>#include <stack>#include <cmath>#include <map>#include <bitset>#include <set>#include <vector>#include <functional>using namespace std;#define pi acos(-1)#define endl '\n'#define rand() srand(time(0));#define me(x) memset(x,0,sizeof(x));#define foreach(it,a) for(__typeof((a).begin()) it=(a).begin();it!=(a).end();it++)#define close() ios::sync_with_stdio(0);typedef long long LL;const int INF=0x3f3f3f3f;const LL LINF=0x3f3f3f3f3f3f3f3fLL;//const int dx[]={-1,0,1,0,-1,-1,1,1};//const int dy[]={0,1,0,-1,1,-1,1,-1};const int maxn=1e6+5;const int maxx=1e6+3;const double EPS=1e-7;const int MOD=10000007;typedef pair<int, int>P;#define mod(x) ((x)%MOD);template<class T>inline T min(T a,T b,T c) { return min(min(a,b),c);}template<class T>inline T max(T a,T b,T c) { return max(max(a,b),c);}template<class T>inline T min(T a,T b,T c,T d) { return min(min(a,b),min(c,d));}template<class T>inline T max(T a,T b,T c,T d) { return max(max(a,b),max(c,d));}//typedef tree<pt,null_type,less< pt >,rb_tree_tag,tree_order_statistics_node_update> rbtree;/*lch[root] = build(L1,p-1,L2+1,L2+cnt); rch[root] = build(p+1,R1,L2+cnt+1,R2);中前*//*lch[root] = build(L1,p-1,L2,L2+cnt-1); rch[root] = build(p+1,R1,L2+cnt,R2-1);中后*/long long gcd(long long a , long long b){if(b==0) return a;a%=b;return gcd(b,a);}int n;int num[maxn];int minsum[maxn][20];int maxsum[maxn][20];void init_RMQ(int n){ for(int i=1;i<=n;i++) maxsum[i][0] = minsum[i][0] = num[i]; int k = log2(1.0*n); for(int j=1;j<=k;j++) { for(int i=1;i<=n;i++) { if(i+(1<<j)-1<=n) { maxsum[i][j] = max(maxsum[i][j-1], maxsum[i+(1<<(j-1))][j-1]); minsum[i][j] = min(minsum[i][j-1], minsum[i+(1<<(j-1))][j-1]); } } }}int getMax(int i,int j){ int k = (int)log2(1.0*(j-i+1)); return max(maxsum[i][k], maxsum[j-(1<<k)+1][k]);}int getMin(int i,int j){ int k = (int)log2(1.0*(j-i+1)); return min(minsum[i][k], minsum[j-(1<<k)+1][k]);}int bsmn(int L){ int l = L+1; int r = n; int ans = L; while(l <= r) { int mid = (l+r)>>1; if(getMin(L+1, mid) > num[L]) { ans = max(ans, mid); l = mid + 1; } else r = mid - 1; } return ans;}int bsmx(int L){ int l = L+1; int r = n; int ans = L; while(l <= r) { int mid = (l+r)>>1; if(getMax(L+1, mid) < num[L]) { ans = max(ans, mid); l = mid + 1; } else r = mid - 1; } return ans;}inline int Scan(){ int res=0,ch,flag=0; if((ch=getchar())=='-')flag=1; else if(ch>='0' && ch<='9')res=ch-'0'; while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-'0'; return flag ? -res : res;}int main(){ n=Scan(); for(int i=1; i<=n; i++) num[i]=Scan(); init_RMQ(n); LL ans = 0; int mxidx = bsmx(1); int mnidx = bsmn(1); ans += 1ll*mxidx*num[1]; ans -= 1ll*mnidx*num[1]; stack<P>mx; stack<P>mn; mx.push(P(num[1], 1)); mn.push(P(num[1], 1)); for(int i=2; i<=n; i++) { mxidx = bsmx(i); mnidx = bsmn(i); int mxk = i; int mnk = i; while(mx.size() && mx.top().first <= num[i]) { mxk = mx.top().second; mx.pop(); } mx.push(P(num[i], mxk)); while(mn.size() && mn.top().first >= num[i]) { mnk = mn.top().second; mn.pop(); } mn.push(P(num[i], mnk)); //printf("%d %d %d %d\n", i-mxk+1, i-mnk+1, mxidx-i+1, mnidx-i+1); ans += 1ll*(i-mxk+1)*num[i]*(mxidx-i+1); ans -= 1ll*(i-mnk+1)*num[i]*(mnidx-i+1); } cout << ans << endl;}
阅读全文
0 0
- codeforces 817D Imbalanced Array
- codeforces 817D Imbalanced Array
- Codeforces 817D Imbalanced Array
- Codeforces 817D Imbalanced Array【思维】好题!
- codeforces 817D Imbalanced Array(单调栈)
- Educational Codeforces Round 23 817-D Imbalanced Array 单调栈
- CodeFroces 817D Imbalanced Array(单调栈)
- codeforce 871D Imbalanced Array
- Educational Codeforces Round 23 D. Imbalanced Array(单调栈或RMQ+二分)
- 【CODEFORCES】 D. Interesting Array
- CodeForces 402D Upgrading Array
- CodeForces 402D Upgrading Array
- Codeforces 86D. Powerful array
- CodeForces 402D Upgrading Array
- Codeforces 86D:Powerful array
- CodeForces 624D Array GCD
- codeforces 86 D Powerful array
- CODEFORCES, 483D Interesting Array
- Android-Activity的基本介绍和页面之间数据传递
- VS的调试:winform中查看控制台输出、查看字符存储位置
- Vim编辑器的安装与使用
- sqlite3工具
- 信息安全代码
- codeforces 817D Imbalanced Array
- 【JZOJ5149】超级绵羊异或 题解
- 诉苦!first
- 代理原理-http,socks5,ssl, shadowsocks
- c++ builder 中的 XMLDocument 类详解(9) -关于 HasChildNodes 与 IsTextElement
- idea创建gradle项目失败 运行环境上下文不一致导致的错误
- NGUI Label打字机效果
- Hadoop mapreduce shuffle
- PAT 1029 Median(中位数+归并排序)