ACdream P1174 Sum

Sum

Time Limit: 6000/3000MS (Java/Others)Memory Limit: 128000/64000KB (Java/Others)

Problem Description

給出N,a[1]... a[N],還有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[N]

第三行M個數字,b[1]..b[M]

(1 <= a[i],b[i] <= 10000)

Output

每組數據一行,ans

Sample Input

4 4
1 2 3 4
5 6 7 8

Sample Output

-40

Hint

you may be TLE if 10000 * 10000 per case

Source

classical

Manager


剛做的一道水題,趁熱寫一發題解。

這題先考慮沒有ABS的情況(ai-bj)*(i-j)把這之類所有式子都寫出,然後合併同類項,可得a數組的項數符合-m(m-1)/2爲首項,差爲m的等差數列,b數組同理。

再考慮有了絕對值怎麼辦,有了絕對值無非是一些小於bj的ai項數(bj類似)出現了變動,故先排序,這樣就可以清楚求出那些ai碰到了哪些bj,發生相應的項數變動。

代碼:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack> 
#include<vector>
#include<cmath>
#define rep(i,n) for(i=1;i<=n;i++)
#define MM(a,t) memset(a,t,sizeof(a))
#define INF 1e9
typedef long long ll;
#define mod 1000000007
using namespace std;
ll ans;
struct node{
  ll  val,index;
  char zl;
}a[100002];
ll cnta[50002],cntb[50002];
ll n,m; 
void setup(){
<span style="white-space:pre">	</span>ll i,j;
<span style="white-space:pre">	</span>ll tmp;
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>cnta[1]=-(m*(m-1)/2);
<span style="white-space:pre">	</span>for(i=2;i<=n;i++)
<span style="white-space:pre">	</span>  cnta[i]=cnta[i-1]+m;
    cntb[1]=-(n*(n-1)/2);
    for(i=2;i<=m;i++)
      cntb[i]=cntb[i-1]+n;
}
bool cmp1(node a1,node a2){
<span style="white-space:pre">	</span>return a1.val<a2.val;
}
ll ReadInt()//輸入掛 
{
    char ch = getchar();
    ll data = 0;
    while (ch < '0' || ch > '9')
        ch = getchar();
    do
    {
        data = data*10 + ch-'0';
        ch = getchar();
    } while (ch >= '0' && ch <= '9');
    return data;
}
int main()
{
<span style="white-space:pre">	</span>ll i,j;
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>while(scanf("%lld%lld",&n,&m)!=EOF){
<span style="white-space:pre">		</span>setup(); ans=0;
<span style="white-space:pre">		</span>rep(i,n){
<span style="white-space:pre">			</span>ll tmp;
<span style="white-space:pre">			</span>tmp=ReadInt();
<span style="white-space:pre">			</span>a[i].zl='a';
<span style="white-space:pre">			</span>a[i].val=tmp;
<span style="white-space:pre">			</span>a[i].index=i;
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>for(i=n+1;i<=n+m;i++){
<span style="white-space:pre">			</span>ll tmp;
<span style="white-space:pre">			</span>tmp=ReadInt();
<span style="white-space:pre">			</span>a[i].zl='b';
<span style="white-space:pre">			</span>a[i].val=tmp;
<span style="white-space:pre">			</span>a[i].index=i-n;
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>sort(a+1,a+n+m+1,cmp1);
<span style="white-space:pre">		</span>ll s1=0,sum1=0;
<span style="white-space:pre">		</span>rep(i,n+m)
<span style="white-space:pre">		</span>if(a[i].zl=='a'){
<span style="white-space:pre">		</span>  s1+=1; sum1+=a[i].index;<span style="white-space:pre">	</span>
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>else cntb[a[i].index]+=2*(sum1-s1*a[i].index);
<span style="white-space:pre">		</span>s1=0; sum1=0;
<span style="white-space:pre">		</span>for(i=n+m;i>=1;i--)
<span style="white-space:pre">		</span>if(a[i].zl=='b'){
<span style="white-space:pre">			</span>s1+=1; sum1+=a[i].index;
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>else cnta[a[i].index]-=2*(s1*a[i].index-sum1);
<span style="white-space:pre">		</span>rep(i,n+m)
<span style="white-space:pre">		</span>if(a[i].zl=='a') ans+=cnta[a[i].index]*a[i].val;
<span style="white-space:pre">		</span>else             ans+=cntb[a[i].index]*a[i].val;
<span style="white-space:pre">		</span>printf("%lld\n",ans);
<span style="white-space:pre">	</span>}


<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>return 0;
}

方法一般,想上進的同學可以去探求更快的方法。出題者卡了個常數來卡我這種做法,但是我機智地用了輸入掛破解了,求管理員繼續卡啊!你要再卡常數這道題就沒意思了,題目出的不夠好請別用卡常數這種低級無聊手段讓我們臣服。


發佈了41 篇原創文章 · 獲贊 1 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章