如何有效地存储和处理此问题的数据?
我们有两个长度为N的数组a和b,最初所有值都等于零。我们有Q操作。让我们在这个数组上定义三种类型的操作:
1 l r c
:通过c增加al,a(l + 1),...,ar。
2 l r c
:通过c增加bl,b(l + 1),...,br。
3 l r
:以模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;
}
}
}
答案 0 :(得分:1)
如何有效地存储和处理此问题的数据?
对于N = 10 9 ,如果仅使用4字节大小的long,则必须存储大约7.4 GB的数据。
这是不可行的,我认为这是问题的重点。
你有200000个Qs - 存储Qs而不是每个Q只占用11个字节 - 一个字节用于确定操作,8个字节用于两个值,最多可以达到10 9 和2个字节对于c,它适合16位,因为它不高于10000。
如果存储Q,最终会得到大约2 MB的数据。
您可以在运行时将Q操作应用于单个long(long),然后单独打印每个值。该算法将具有内存效率,但速度非常慢。
看看这个问题,我们会有很多具有相同值的数组成员。只有200000个操作,但是1000000个数组条目 - 我们可以更改200000个不同的值 - 如果我们这样做,我们仍然有(10 9 - 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) )* O(n)。
但是如果我们将数据放入二叉搜索树中,我们可以在200000个条目中以18个步骤找到正确的数组条目。这花费了我们更多的内存,不仅仅是由于开销,而且由于我们需要将数组索引作为键,我们不能将所有相同的值组合在一起,只要它们是一个范围。因此,上面的示例将在二叉搜索树中需要4个节点,以将值0分开两次。
因此,当您将这两种方法结合使用时,您应该能够获得不错的内存和处理器时间消耗。