Ikbal 有两个长度为 N 的数组 a 和 b,最初所有值都为零。
Posted
技术标签:
【中文标题】Ikbal 有两个长度为 N 的数组 a 和 b,最初所有值都为零。【英文标题】:Ikbal has two arrays a and b of length N, initially all values equals to zero. 【发布时间】:2015-09-13 03:52:02 【问题描述】:我试图用下面的代码解决这个问题。但并非所有输入的答案都是准确的。 问题陈述
我们有Q操作。让我们在这个数组上定义三种类型的操作:
1 l r c 将 al,al+1,...,ar 增加 c。
2 l r c 将 bl,bl+1,...,br 增加 c。
3 l r 以 1000000007 为模打印 (al∗bl)+(al+1∗bl+1)+...+(ar∗br) 输入格式
输入的第一行由 N 和 Q 组成。接下来的 Q 行包含三种操作类型之一。
约束
1≤N≤109 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 说明
第一次操作后的数组是这样的:
a=5,5,5,5,5
b=0,0,0,0,0 第二次操作后的数组是这样的:
a=5,5,5,5,5
b=0,2,2,2,0
第三次运算的答案:5∗2+5∗2=20
**我的代码**
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
vector<int> a,b,c;
int n,q,r,p;
cin >> n;
cin >> q;
for(int i=0;i<q;i++)
cin >> r;
a.push_back(r);
if(r==3)
p = 3;
else
p = 4;
for(int j=1;j<p;j++)
cin >> r;
a.push_back(r);
vector<int> aa(n,0),bb(n,0);
int g,start,endd,val,anss=0;
for(int i=0;i<a.size();)
if(a[i]==3)
start = a[i+1]-1;
endd = a[i+2]-1;
if(start==endd)
anss = (aa[start]*bb[start])%1000000007;
else
anss = (aa[start]*bb[start] + aa[endd]*bb[endd])%1000000007;
cout << anss << endl;
i+= 3;
else
start = a[i+1] - 1;
endd = a[i+2];
val = a[i+3];
if(a[i]==1)
for(int j=start;j<endd;j++)
aa[j] += val;
else
for(int j=start;j<endd;j++)
bb[j] += val;
i+= 4;
/*
for(int i=0;i<n;i++)
cout << aa[i] << " " ;
cout << bb[i] << endl;
for(int i=0;i<a.size();i++)
cout << a[i] << endl;
*/
return 0;
给定输入的预期输出: http://i.stack.imgur.com/4OsSo.jpg
【问题讨论】:
anss = (aa[start]*bb[start])%1000000007;
和 anss = (aa[start]*bb[start] + aa[endd]*bb[endd])%1000000007;
可能会导致整数溢出。您可以通过这种方式在模 1000000007 中添加和乘以 32 位整数,例如:ideone.com/V0mDWb
别忘了提到你想在编程比赛中作弊hackerrank.com/contests/worldcup/challenges/two-arrays-1
同***.com/questions/32536920/…
【参考方案1】:
这不是溢出问题。这个:
if(start==endd)
anss = (aa[start]*bb[start])%1000000007;
else
anss = (aa[start]*bb[start] + aa[endd]*bb[endd])%1000000007;
完全错误。您误读了说明。
【讨论】:
【参考方案2】: 注意不要造成溢出。 你必须计算(al∗bl)+(al+1∗bl+1)+...+(ar∗br)
,而不是(al∗bl)+(ar∗br)
至少,给定输入的输出
10 20
1 9 9 6768
2 5 5 2202
3 7 7
2 3 9 1167
2 1 7 8465
3 1 5
2 1 1 1860
3 9 9
2 5 5 2153
1 5 7 749
3 1 1
2 8 10 3129
3 1 1
1 2 10 2712
2 1 8 79
1 1 6 4645
1 7 7 1358
3 2 10
1 9 9 8677
3 8 10
已更正。
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int add(int a, int b)
int r = a + b;
if (r >= 1000000007) r -= 1000000007;
return r;
int mul(int a, int b)
int r = 0;
while (b > 0)
if (b % 2 != 0) r = add(r, a);
a = add(a, a);
b /= 2;
return r;
int main()
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
vector<int> a,b,c;
int n,q,r,p;
cin >> n;
cin >> q;
for(int i=0;i<q;i++)
cin >> r;
a.push_back(r);
if(r==3)
p = 3;
else
p = 4;
for(int j=1;j<p;j++)
cin >> r;
a.push_back(r);
vector<int> aa(n,0),bb(n,0);
int g,start,endd,val,anss=0;
for(int i=0;i<a.size();)
if(a[i]==3)
start = a[i+1]-1;
endd = a[i+2]-1;
#if 0
if(start==endd)
anss = (aa[start]*bb[start])%1000000007;
else
anss = (aa[start]*bb[start] + aa[endd]*bb[endd])%1000000007;
#else
anss = 0;
if (start <= endd)
for(int j=start;j<=endd;j++)anss = add(anss, mul(aa[j], bb[j]));
else
for(int j=endd;j<=start;j++)anss = add(anss, mul(aa[j], bb[j]));
#endif
cout << anss << endl;
i+= 3;
else
start = a[i+1] - 1;
endd = a[i+2];
val = a[i+3];
if(a[i]==1)
for(int j=start;j<endd;j++)
#if 0
aa[j] += val;
#else
aa[j] = add(aa[j], val);
#endif
else
for(int j=start;j<endd;j++)
#if 0
bb[j] += val;
#else
bb[j] = add(bb[j], val);
#endif
i+= 4;
/*
for(int i=0;i<n;i++)
cout << aa[i] << " " ;
cout << bb[i] << endl;
for(int i=0;i<a.size();i++)
cout << a[i] << endl;
*/
return 0;
【讨论】:
以上是关于Ikbal 有两个长度为 N 的数组 a 和 b,最初所有值都为零。的主要内容,如果未能解决你的问题,请参考以下文章
给定一个长度为N的数组,找出出现次数大于n/2,n/3的数,要求时间复杂度O(n),空间复杂度O
2022-01-02:给定两个数组A和B,长度都是N, A[i]不可以在A中和其他数交换,只可以选择和B[i]交换(0<=i<n), 你的目的是让A有序,返回你能不能做到。