Logo S08577 的博客

博客

mx 731 模拟赛记录

...
S08577
2025-12-01 12:57:31

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2024-07-31 21:27:06

A

题意

Arc158C

思路

形象化题意:

$$\sum_{i=1}^{N} \sum_{j=1}^{N}f(A_i+A_j)$$

其中,$f(i)$ 为 $i$ 的数位和。

显然,这个式子十分的不美观,且 $f(A_i+A_j)$ 也比较难求,不妨将其拆成 $f(A_i)+f(A_j)$。但是,两个数的和的数位和 和 两个数的数位和的和显然不同。

举个例子:

$$5 \ 6 \ 7$$ $$7 \ 8 \ 9$$

相加得到:

$$1 \ 3 \ 5 \ 6$$

第一个数的数位和为18,第二个数的数位和为24,两数和的数位和为15。

但是,仔细思考不难得出,进位一次,数位和会减去9。

所以,我们不难推出这个式子:

$$f(A_i+A_j)=f(A_i)+f(A_j)-9\times g(A_i,A_j)$$

其中,$g(A_i,A_j)$ 是 $A_i$ 和 $A_j$ 相加进位的次数。

整个式子便可化为:

$$\sum_{i=1}^{N} \sum_{j=1}^{N}f(A_i)+f(A_j)-9\times g(A_i,A_j)$$

其中:$\sum_{i=1}^{N} \sum_{j=1}^{N}f(A_i)+f(A_j)$ 等价为 $2 \times n(\sum_{i=1}^{N} f(A_i))$。

分析 $g(a,b)$,发现在第 $d$ 位上有进位当且仅当 $a \ mod \ 10^d + b \ mod \ 10^d \ge 10^{d+1}$。我们可以二分求答案。

代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<stack>
#include<map>
#include<queue>


using namespace std;

#define int long long
#define ll long long
#define Endl cout<<endl;
#define xy cout<<"xy";
#define yx cout<<"yx";
#define pii pair<int,int>
#define ls(rt) tr[rt].ch[0]
#define rs(rt) tr[rt].ch[1]
#define lowbit(x) x&(-x)

const int N=1e6+5;\/\/注意修改
const int mod=1e9+7;
const int Max=2e6+10;

int n,m;
int a[20][N],b[N];



signed main(){
        
    int n;
    cin>>n;
    int sum=0;
    for(int i=1;i<=n;i++) {
        int t;
        cin>>t;
        int tmp=10;
        for(int j=1;j<=15;j++){
            a[j][i]=t%tmp;
            tmp*=10;
        }
        while(t){
            int tt=t%10;
            sum+=tt;
            t\/=10;
        }
    }
    sum*=2*n;
    \/\/cout<<sum<<endl;
    int Tt=1;
    for(int i=1;i<=15;i++){
        Tt*=10;
        sort(a[i]+1,a[i]+1+n);
        for(int j=1;j<=n;j++){
            sum-=9*(a[i]+n+1-lower_bound(a[i]+1,a[i]+1+n,Tt-a[i][j]));
           
        }

    }
    
    cout<<sum<<endl;
    
    return 0;
}


\/*

 *\/

B

时间到了,写不了了,以后有时间在写。

代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<stack>
#include<map>
#include<queue>


using namespace std;

#define int long long
#define ll long long
#define Endl cout<<endl;
#define xy cout<<"xy";
#define yx cout<<"yx";
#define pii pair<int,int>
#define ls(rt) tr[rt].ch[0]
#define rs(rt) tr[rt].ch[1]
#define lowbit(x) x&(-x)

const int N=1e6+5;\/\/注意修改
const int mod=1e9+7;
const int Max=2e6+10;

int n,m;
int a[20][N],b[N],p[N];
int x,k;
int sum=0,cnt=0;

int tot=0;

void dfs(int x,int y){ \/\/要拆分得数是x,拆到了第y层
    \/\/cout<<x<<' '<<y<<endl;
    if(tot>=100000) return ;
    if(y==0||x==1){
        tot++;
        cout<<x<<' ';
        sum+=x;
        return ;
    }
    if(tot>=100000) return ;
    for(int i=1;i<=cnt;i++){
        if(p[i]>x||tot>100000) return ;
       if(x%p[i]==0) dfs(p[i],y-1);
    }
}

signed main(){
    
\/\/    freopen("digit.in","r",stdin);
\/\/    freopen("digit,out","w",stdout);
    
    cin>>x>>k;
    
    for(int i=1;i*i<=x;i++){
        if(x%i==0) p[++cnt]=i;
    }
    int d=cnt;
    for(int i=d;i>=1;i--){
        if(p[i]*p[i]!=x){
            p[++cnt]=x\/p[i];
          \/\/  cout<<p[i]<<' ';
        }
    }
\/\/    for(int i=1;i<=cnt;i++) {
\/\/        cout<<p[i]<<' ';
\/\/    }
    dfs(x,k);
    
    return 0;
}


\/*

 *\/


评论

暂无评论

发表评论

可以用@mike来提到mike这个用户,mike会被高亮显示。如果你真的想打“@”这个字符,请用“@@”。