ACDream - Sum
2014-08-01 12:20
302 查看
先上题目:
SubmitStatus
,还有M,b[1]... b[M]
long long ans = 0;
for(int i = 1; i <= N; i ++)
for(int j = 1; j <= M; j ++)
ans += abs(a[i] - b[j]) * (i - j);
第一行N,M(1 <= N,M <= 50000)
第二行N个数字,a[1].. a
第三行M个数字,b[1]..b[M]
(1 <= a[i],b[i] <= 10000)
[align=center]SubmitStatus[/align]
[align=center] [/align]
[align=center] 这一题最简单的思路就是直接枚举,但是这样绝对会TLE,然后稍微优化一下将运算的公式分成两种情况(a[i]>=b[j] || a[i]<b[j]),然后将公式拆开,得到四项,我们可以先预处理出前n项的j,b[j]*j,b[j]的和,然后枚举a[i],求出(a[i]>=b[j] 和 a[i]<b[j])的分界线,然后求两端的和即可。至于求分界线的方法,一种是用lower_bound求,该操作加上枚举a[i]的时间复杂度是O(nlogn),这样经过试验会超时。另外一种方法是用树状数组求,经小伙伴的测试好像也会超时······。[/align]
[align=center] 不会超时的方法是除了对b排序以外对a也排个序,然后预处理出每个a[i]的边界loc[i]。这样做的时间复杂度是O(n),总的时间复杂度是O(nlogn),不会超时。[/align]
[align=center] [/align]
[align=center]上代码:[/align]
[align=center] [/align]
/*Sum*/
Sum
Time Limit: 6000/3000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others)SubmitStatus
Problem Description
给出N,a[1]... a,还有M,b[1]... b[M]
long long ans = 0;
for(int i = 1; i <= N; i ++)
for(int j = 1; j <= M; j ++)
ans += abs(a[i] - b[j]) * (i - j);
Input
多组数据,每组数据第一行N,M(1 <= N,M <= 50000)
第二行N个数字,a[1].. a
第三行M个数字,b[1]..b[M]
(1 <= a[i],b[i] <= 10000)
Output
每组数据一行,ansSample Input
4 4 1 2 3 4 5 6 7 8
Sample Output
-40
Hint
you may be TLE if 10000 * 10000 per case[align=center]SubmitStatus[/align]
[align=center] [/align]
[align=center] 这一题最简单的思路就是直接枚举,但是这样绝对会TLE,然后稍微优化一下将运算的公式分成两种情况(a[i]>=b[j] || a[i]<b[j]),然后将公式拆开,得到四项,我们可以先预处理出前n项的j,b[j]*j,b[j]的和,然后枚举a[i],求出(a[i]>=b[j] 和 a[i]<b[j])的分界线,然后求两端的和即可。至于求分界线的方法,一种是用lower_bound求,该操作加上枚举a[i]的时间复杂度是O(nlogn),这样经过试验会超时。另外一种方法是用树状数组求,经小伙伴的测试好像也会超时······。[/align]
[align=center] 不会超时的方法是除了对b排序以外对a也排个序,然后预处理出每个a[i]的边界loc[i]。这样做的时间复杂度是O(n),总的时间复杂度是O(nlogn),不会超时。[/align]
[align=center] [/align]
[align=center]上代码:[/align]
[align=center] [/align]
/* * this code is made by sineatos * Problem: 1174 * Verdict: Accepted * Submission Date: 2014-08-01 12:08:56 * Time: 2488MS * Memory: 3240KB */ #include <cstdio> #include <cstring> #include <utility> #include <algorithm> #define MAX 50002 #define ll long long using namespace std; typedef pair<int,int> pii; pii a[MAX],b[MAX]; int n,m; ll sumb[MAX],sumbj[MAX],sumj[MAX]; int loc[MAX]; inline ll Sum(int i,int r,int l){ ll sum=0; sum=(ll)a[i].first*a[i].second*(r+1-l) - (ll)a[i].first*(sumj[r]-sumj[l-1]) -(ll)a[i].second*(sumb[r]-sumb[l-1]) + (sumbj[r]-sumbj[l-1]); return sum; } int main() { ll sum; //freopen("data.txt","r",stdin); while(scanf("%d %d",&n,&m)!=EOF){ for(int i=1;i<=n;i++){ scanf("%d",&a[i].first); a[i].second=i; } for(int i=1;i<=m;i++){ scanf("%d",&b[i].first); b[i].second=i; } sort(a+1,a+n+1); sort(b+1,b+m+1); sumb[0]=sumbj[0]=sumj[0]=0; int k=1; for(int i=1;i<=n;i++){ while(k<=m && a[i].first>=b[k].first) k++; loc[i]=k; } for(int i=1;i<=m;i++){ sumb[i]=sumb[i-1]+b[i].first; sumbj[i]=sumbj[i-1]+(ll)b[i].first*b[i].second; sumj[i]=sumj[i-1]+b[i].second; } sum=0; for(int i=1;i<=n;i++){ int mid=loc[i]; ll p1=Sum(i,m,mid); ll p2=Sum(i,mid-1,1); sum+=p2-p1; } printf("%lld\n",sum); } return 0; }
/*Sum*/
相关文章推荐
- ACdream 1139(Sum-逆元)
- ACdream: Sum
- ACdreamOJ 1154 Lowbit Sum (数字dp)
- 数位DP ACdream 1154 Lowbit Sum
- acdream Divide Sum
- Sum vs Product(ACdream) —— dfs
- acdream 1431 Sum vs Product
- ACdream OJ 1154 Lowbit Sum
- ACdreamOJ 1154 Lowbit Sum (数位dp)
- ACdream 1431 Sum vs Product
- 杭电 HDU OJ Max Sum ID1003 AC
- ACdream oj C - 神奇的%系列一 (水题系列--略坑)
- Acdreamoj1115(数学思维题)
- Acdreamoj1115(数学思维称号)
- AC_Dream 1224 Robbers(贪心)
- ACdream OJ 1140 Counting Triangles
- acdream 1014 Dice Dice Dice(组合)
- ACdream 1071 神奇的%系列一 筛选法
- acdream.A Very Easy Triangle Counting Game(数学推导)
- ACdreamoj(1105)模拟题