繁体   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