簡體   English   中英

在C中存儲和處理大量數據

[英]Storing and processing large amount of data in C

如何有效地存儲和處理此問題的數據?

問題陳述

我們有兩個長度為N的數組a和b,最初所有值都等於零。 我們有Q操作。 讓我們在此數組上定義三種類型的操作:

1 lrc :將al,a(l + 1),...,ar按c增加。

2 lrc :將b,b(l + 1),...,br增加c。

3 lr :以模1000000007打印(al * bl)+ a(l + 1)* b(l + 1)+ ... +(ar * br)。

輸入格式

輸入的第一行包含N和Q。接下來的Q行包含三種運算類型之一。

約束條件

1≤N≤10 ^ 9
1≤Q≤200000
1≤c≤10000
1≤l≤r≤N

輸出格式

每當您進行3類操作時,都應在新行中打印答案。

樣本輸入

5 3 
1 1 5 5 
2 2 4 2 
3 3 4

樣本輸出

20

我在C中的代碼

#include<stdio.h>
#include<string.h>
int main()
{
    long n,q,ch,l,r,c,i,j;
    /* n, q, l, r, c works as per problem statement.
       ch is used to scan the first digit of operation.
       i and j are used to control the loops. */
    scanf("%ld %ld",&n,&q);
    long a[n],b[n];
    memset(&a, 0, sizeof a);
    memset(&b, 0, sizeof b);
    for(i=0;i<n;i++)    //Init to 0
    {
        a[i]=0;
        b[i]=0;
    }
    for(i=0;i<q;i++)
    {
        scanf("%ld ",&ch);  //Look for the first digit
        switch(ch)
        {
            case 1:
                scanf("%ld %ld %ld",&l,&r,&c);
                l--;
                for(j=l;j<r;j++)
                    a[j]+=c;    //Adds c to every element of a
                break;
            case 2:
                scanf("%ld %ld %ld",&l,&r,&c);
                l--;
                for(j=l;j<r;j++)
                    b[j]+=c;    //Adds c to every element of b
                break;
            case 3:
                scanf("%ld %ld",&l,&r);
                l--;
                c=0;
                for(j=l;j<r;j++)
                    c+=a[j]*b[j];   //Adds the product
                printf("%ld\n",c%1000000007);   //Prints the value after using mod
                break;
        }
    }
}

如何有效地存儲和處理此問題的數據?

對於N = 10 9 ,如果僅使用4字節大小的long,則必須存儲大約7.4 GB數據。

這是不可行的,我認為這是問題的全部重點。

您有200000個Q-存儲Q則每個Q僅占用11個字節-一個字節來確定操作,兩個值分別為8個字節(最多可以為10 9)和c的2個字節(適合16位),如下所示不高於10000。

如果存儲Q,最終將獲得大約2 MB的數據。

您可以在運行時將Q操作應用於單個long(長整數),然后分別打印每個值。 該算法將提高內存效率,但速度非常慢。

着眼於這個問題,我們將擁有許多具有相同值的數組成員。 只有200000級的操作,但10億數組項-我們可以改變不同的200000個值-如果我們這樣做,我們仍然有(109 - 200000)具有非常相同的值數組項。 即使我們修改了200000范圍,也不會改變事實,只是改變不同值的分布。 因此,存儲一個值,然后存儲該值對哪個數組范圍有效得多。

例如:

value 0 - [0,4343] [489289,999999999]
value 3 - [4344,4345]
value 7 - [4346,489288]

這是存儲值和存儲操作的混合。 當需要打印一個值時,您可以查找范圍並打印該值。

如您所見,對於這個簡單的示例,我們需要少於64個字節來存儲如何破壞7.4 GB數據的信息,但是我們可以為每個數組位置打印該值。

即使我們減少了數據,我們仍然需要優化其余數據。 我們不能只是將其轉儲到鏈表中-如前所述,我們可以得到Q + 1個條目(200001),我們不能用O(n)的努力來搜索這些條目,更不用說(rl ) * 上)。

但是,如果將數據放入二叉搜索樹中,則可以在200000條目中的18個步驟中找到正確的數組條目。 這不僅使開銷大,而且使我們花了更多的內存,而且由於我們需要數組索引作為鍵,因此,只要它們是一個范圍,就不能將所有相同的值組合在一起。 因此,上面的示例將在二進制搜索樹中需要4個節點,以將值0分隔兩次。

因此,當您將這兩種方法結合使用時,您應該能夠獲得不錯的內存和處理器時間消耗。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM