智算复赛


解法:枚举

#include <bits/stdc++.h>
typedef  long long ll ;
#define int ll
using namespace std ;
int quickpow(int a,int b,int mo){int s;for(s=1;b;b>>= 1,a=a*a%mo)if(b&1)s=s*a%mo;return s;}
#define INF 0x3f3f3f3f
const double PI = acos(-1.0);
const int maxn = 2e3+9;
const int mod = 998244353;

void Solve(){
    int aa , b ;
    scanf("%lld%lld" , &aa , &b);
    if(b == 1){
        puts("900");
    }else if(b == 2){
        if(aa%2) puts("0");
        else puts("900"); 
    }else{
        int a = aa , len = 1 ;
        while(a){
            a /= 10 ;
            len *= 10 ;
        }
        int cnt = 0 ;
        for(int i = 1 ; i <= 9 ; i++){
            for(int j = 0 ; j <= 9 ; j++){
                for(int k = 0 ; k <= 9 ; k++){
                    int n = i*len*100+j*len*10+k*len+aa;
                    if(n%b==0){
                        cnt++;
                    }
                }
            }
        }
        printf("%lld
" , cnt);
    }

}
signed main(){
    #ifdef ONLINE_JUDGE
    #else
        freopen("D:\c++\in.txt", "r", stdin);
        //freopen("D:\c++\out.txt", "w", stdout);
    #endif
    //int t ;
    //cin >> t ;
    //while(t--)
        Solve();
}


解法:一共要走2*n次,第一种方案每次走1,第二个方案每次走2,对比两种方案的性价比
如果第二种更优,则最大化选第二种,对坐标排序,类似最长子序列。

#include <bits/stdc++.h>
typedef  long long ll ;
//#define int ll
using namespace std ;
int quickpow(int a,int b,int mo){int s;for(s=1;b;b>>= 1,a=a*a%mo)if(b&1)s=s*a%mo;return s;}
#define INF 0x3f3f3f3f
const double PI = acos(-1.0);
const int maxn = 2e3+9;
const int mod = 998244353;

int dp[maxn];

struct node{
    int x , y ;
}a[maxn];

bool cmp(node a , node b){
    if(a.x != b.x) return a.x < b.x;
    return a.y < b.y ;
}
void Solve(){
    int n , k , w1 , w2;
    scanf("%d%d%d%d" , &n , &k , &w1 , &w2);
    for(int i = 1 ; i <= k ; i++){
        scanf("%d%d" , &a[i].x , &a[i].y);
        dp[i] = 1 ;
    }
    if(2*w1 <= w2){
        printf("%lld
" , 2ll*n*w1);
    }else{
        sort(a+1 , a+1+k , cmp);
        for(int i = 1 ; i <= k ; i++){
            for(int j = 1 ; j < i ; j++){
                if(a[i].x > a[j].x && a[i].y > a[j].y){
                    dp[i] = max(dp[i] , dp[j] + 1);
                }
            }
        }
        int ma = 0;
        for(int i = 1 ; i <= k ; i++){
            ma = max(ma , dp[i]);
        }
        printf("%lld
" , 2ll*(n-ma)*w1 + 1ll*ma*w2);
    }
}
   
   
signed main(){
    #ifdef ONLINE_JUDGE
    #else
        freopen("D:\c++\in.txt", "r", stdin);
        //freopen("D:\c++\out.txt", "w", stdout);
    #endif
    //int t ;
    //cin >> t ;
    //while(t--)
        Solve();
}


解法:对于66个点,要构造出2的64次方的方案数,除去两个端点,根据二进制,这64个点每个点应该可以表示一位权值。

#include <bits/stdc++.h>
typedef unsigned long long ll ;
#define int ll
using namespace std ;
int quickpow(int a,int b,int mo){int s;for(s=1;b;b>>= 1,a=a*a%mo)if(b&1)s=s*a%mo;return s;}
#define INF 0x3f3f3f3f
const double PI = acos(-1.0);
const int maxn = 1e4+9;
const int mod = 998244353;


void Solve(){
    int k , n ;
    cin >> k >> n ;
    if(k == 1){
        printf("2 1
1 2
");
    }else if(k == 2){
        printf("3 3
1 2
2 3
1 3
");
    }else if(k == 3){
        printf("4 5
1 2
1 3
3 2
2 4
1 4
");
    }else{
        int cnt = 2016+64; 
        for(int i = 0 ; i <= 63 ; i++){
            if((k>>i)&1){
                cnt += 1 ;
            }
        }
        printf("66 %lld
" , cnt);
        for(int i = 2 ; i <= 65 ; i++){
            printf("1 %lld
" , i);
            for(int j = i+1 ; j <= 65 ; j++){
                printf("%lld %lld
" , i , j);
            }
        }
        for(int i = 0 ; i <= 63 ; i++){
            if((k>>i)&1){
                printf("%lld 66
" , i+2);
            }
        }
    }
}
   
   
signed main(){
    #ifdef ONLINE_JUDGE
    #else
        freopen("D:\c++\in.txt", "r", stdin);
        //freopen("D:\c++\out.txt", "w", stdout);
    #endif
    //int t ;
    //cin >> t ;
    //while(t--)
        Solve();
}


题意:求1-n的lcm
解法:每个只有一种素因子的数对答案有贡献,筛法时直接处理,注意数据范围要开无符号长整型。
欧拉筛更快,但注意会MLE,素数表长度不需要7e8.标记数组开bool

#include <bits/stdc++.h>
typedef long long ll ;
//#define int ll
int quickpow(int a,int b,int mo){int s;for(s=1;b;b>>= 1,a=a*a%mo)if(b&1)s=s*a%mo;return s;}
using namespace std ;
#define INF 0x3f3f3f3f
const double PI = acos(-1.0);
const int maxn = 8e7+1;
const ll mod =  4294967296 ;

int pr[5000000] , len;
bool is[maxn];
int vis[maxn];
void Solve(){
    int n ;
    ll a , b;
    scanf("%d%lld%lld" , &n , &a , &b);
    for(int i = 2 ; i <= n ; i++){
        if(!is[i]){
            pr[++len] = i ;
            for(ll j = i ; j <= n ; j *= i){
                vis[j] = i;
            }
        }
        for(int j = 1 ; 1ll*i*pr[j] <= n ; j++){
            is[i*pr[j]] = 1 ;
            if(i%pr[j] == 0){
                break;
            }
        }
    }
    for(int i = 1 ; i <= n ; i++){
        if(vis[i]){
            a = (a * vis[i] + b)%mod;
        }
    }
    printf("%lld
" , a);
}
 
signed main(){
    #ifdef ONLINE_JUDGE
    #else
        freopen("D:\c++\in.txt", "r", stdin);
    #endif
     //int t ;
     //scanf("%lld" , &t);
     //while(t--)
        Solve();
}
原文地址:https://www.cnblogs.com/nonames/p/13472393.html