【2018年廣東工業大學文遠知行杯新生程序設計競賽】灰暗而空虛的景色β

http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1009&cid=832

Problem Description

In the world line 1.048596%

“雪啊。”

“雪是紅色的。”

像壞掉的復讀機一樣,梓川咲太只能把閃爍的思緒斷斷續續的說出來。

“這,是夢吧。”

從口中滑出的卻是這樣的話。

回過神的時候,天空即將被冰冷黑暗的天空吞沒,而自己已經站在湘南臺站附近的圖書館的門口。那是第一次遇見櫻島麻衣的地方,是一切的開端。

無所謂了,已經沒有可以稱爲家而能回去的地方了。就在梓川咲太開始自暴自棄的躺在地上任由黑暗吞噬的時候。

眼前突然出現了穿着白大褂的年輕女子,在昏暗的路燈下,隨風飄揚的似乎是紅色的秀髮。

“不要去輕易的改變過去。”開口便是這麼難懂的話。

“打個比方,對於一個長度爲n,所有元素都爲0的數列。每次操作都選取一個位置,使得從這個位置往後都變成1,4,9,16...i^2 ”

“不可思議啊,爲什麼我一直在,爲什麼你們,一直在讓我做這種數學題。”梓川咲太快瀕臨崩潰了。

“爲了拯救櫻島麻衣和牧之原翔子。這樣的理由夠充分嗎?”那位女子的一句話,讓咲太的精神從深海下看到一束光。

“你能計算出經過這麼多次操作以後變得面目全非的數列的和嗎?”

“不可隨便改變過去,就剛纔那個比方來說,如果有很多次這樣的操作,那麼這個數列的和也很難計算吧。”

“可你現在就是面臨這個問題哦。計算出那個數列的和,你一定能夠知道答案。”這是隻有擁有確信的心的人才能說出來的話。

“算出來以後呢。”梓川咲太還需要最後一塊拼圖。

“去找牧之原翔子吧,一切因她而始,也必定一切因她而終。”

時間的流動在慢慢的將咲太喚回現實。

“許多失敗了的未來,無法挽回的過去,但是肯定在這之後,會有連接到......”

熟悉的話語再次傳來。但話語的主人已經消失在夜空裏。

 

 

Input

第一行輸入一個數字T(T<=10)表示數據有多少組;

每一組數據第一行包含兩個整數n(1<=n<=1e9),Q(Q<=5e4),分別表示數列的長度以及操作的個數。

接下來的Q個數按照操作的時間順序給出每次操作選擇的位置.

 

 

Output

輸出一個數字表示這個數列的和,由於答案可能很大,所以你需要將答案mod 123456789。

 

 

Sample Input


 

1 3 2 3 1

 

 

Sample Output


 

14

思路:

這道題有多次詢問,我們可以將詢問都存起來,然後倒着執行,因爲後一個操作會覆蓋前面的操作因此,最後一個執行的一定沒有被覆蓋,而倒數第二個的操作,有兩種可能一是在上一個操作的區間內部,那麼我們就跳過這一次操作。二是他的操作區間比最後一次還要長,那麼這次操作區間就是,從這次的起點開始,到上一次的中點結束。就這段區間的和,就可以藉助公式了。

1^2+2^2+3^2+...+x^2=\frac{x*(x+1)*(2*x+1)}{6}

這裏的數會很大,因此我們需要藉助取餘操作,一開始想的是求逆元,但是發現這裏求不出逆元,後來經zxz大佬的提醒想起了另一種做法。就是可以用這個公式x/d%k=x%(d*k)/d。

ac代碼:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<string.h>
#define ll long long
#define ull unsigned long long
#define mod 123456789 
using namespace std;
ll cal(ll x)
{
    return (((x*(x+1))%(mod*6)*(2*x+1))%(mod*6))/6;
}
int n;
int a[1010101],num[1010101];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {    
        int  q,n;
        scanf("%d%d",&n,&q);
        for(int i=0;i<q;i++)
        {
            cin>>a[i];
        }
        ll ans=0,ed=n;
        for(int i=q-1;i>=0;i--)
        {
            if(a[i]<ed)
            {
                ans=(ans+cal(ed-a[i]+1))%mod;
                ed=a[i]-1;
            }
            
        }
        cout<<ans%mod<<endl;
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章