[英]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
#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.