其他分享
首页 > 其他分享> > P2671 [NOIP2015 普及组] 求和

P2671 [NOIP2015 普及组] 求和

作者:互联网

题目链接:P2671 [NOIP2015 普及组] 求和icon-default.png?t=LA92https://www.luogu.com.cn/problem/P2671

 

题目分析(结合题解整理出我能看懂的)

20分做法

看完这题,第一想法当然是无脑暴力啦...直接枚举x,y,z,看是否满足条件即可。算法复杂度为O(N^3)O(N3)。[代码就算了]

这样就可得20分了。当然,如果你想用更高级的算法不开long long也是可以的。

40分做法

可以直接枚举x,z的值,通过条件(1)求出y。再看是否满足条件。算法复杂度为O(N^2)

40~50分做法

仍然是枚举x,z的值,但可以先分析x+z=2*y的奇偶性,因为xyz是整数,因此2y是2的倍数,因此x,z必然都为偶数或奇数,因此可以分奇偶性进行枚举,此时这个三元组即可不考虑y值的大小,即为当(i%2==1)枚举前面奇数序列相同的颜色进行算分数即可,算法复杂度为O(N^2/2)。

100分做法

通过上面的观察我们可以发现倒回去算前面的分数可能比较浪费时间,因此,我们采用数学的方法来优化

 

 

 

AC CODE

#include <cstdio>

const int N = 100000;
const int M = 10007;
int n, m;
int sum[N + 1][2], nt[N + 1][2];
int color[N + 1], number[N + 1];
long long ans = 0;

int main()
{
    scanf(" %d %d", &n, &m);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &number[i]);
        number[i] %= M;
    }
    for(int i = 1; i <= n; i++) {
        scanf("%d", &color[i]);
        int c = color[i];
        int g = i % 2;
        nt[c][g]++;
        sum[c][g] += number[i];
        sum[c][g] %= M;
    }
    for(int i = 1; i <= n; i++) {
        int c = color[i];
        int g = i % 2;
        ans += i % M * ((sum[c][g] + (nt[c][g] - 2) % M * number[i] + M) % M);
        ans %= M;
    }
    printf("%lld", ans);
    return 0;
}

侵删 

标签:P2671,NOIP2015,求和,复杂度,算法,long,int,枚举
来源: https://blog.csdn.net/m0_56722204/article/details/121302907