题解:P2671 [NOIP 2015 普及组] 求和

2025.2.16 by Xuancheng_Mao

暴力:(20分)

#include<bits/stdc++.h>
using namespace std;
const int mn=1e5+5;
int n,m,number[mn],color[mn],ans;

bool check(int x,int y,int z){
    if((y-x)==(z-y) && color[x]==color[z]){
        return true;
    }
    return false;
}

int main(){
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>number[i];
    for(int i=1;i<=n;i++) cin>>color[i];
    for(int x=1;x<=n;x++){
        for(int y=x+1;y<=n;y++){
            for(int z=y+1;z<=n;z++){
                if(check(x,y,z)) ans+=(x+z)*(number[x]+number[z]);
                ans%=10007;
            }
        }
    }
    cout<<ans<<'\n';
    return 0;
}

可以看到 与分数无关,只要使 ,故

优化后代码(40分):

#include<bits/stdc++.h>
using namespace std;
const int mn=1e5+5;
int n,m,number[mn],color[mn],ans;

int main(){
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>number[i];
    for(int i=1;i<=n;i++) cin>>color[i];
    for(int x=1;x<=n;x++){
        for(int z=x+2;z<=n;z+=2){
            if(color[x]==color[z]) ans+=(x+z)*(number[x]+number[z]);
            ans%=10007;
        }
    }
    cout<<ans<<'\n';
    return 0;
}

,如何快速计算 是最大的问题。

1 2 3 4 5
1
2
3
4
5

( 简化为 )

发现规律了吗?

记录奇数颜色或偶数格子,用 记录奇数颜色或偶数格子的数字之和。故

正确代码:

#include<bits/stdc++.h>
using namespace std;
const int mn=1e5+5;
int n,m,number[mn],color[mn],ans,s1[mn][2],s2[mn][2];

int main(){
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>number[i];
    for(int i=1;i<=n;i++){
        cin>>color[i];
        s1[color[i]][i%2]++,s2[color[i]][i%2]=(s2[color[i]][i%2]+number[i])%10007;
    }
    for(int i=1;i<=n;i++){
        ans+=i*(s2[color[i]][i%2]+number[i]*(s1[color[i]][i%2]-2)%10007)%10007;
        ans%=10007;
    }
    cout<<ans<<'\n';
    return 0;
}

坑点:一定要记得多次取模!取模!取模!