2025-11-06

CF补题

Problem - 515C - Codeforces(1400)(string+a little factorial)

这题妙在把各个数字阶乘转换成仅含有2 3 5 7 数字,然后直接求解
要对每个数的阶乘进行换算
要找x的最大值,位数多是首要,接着就是从大到小排序

   9 is 7!*8*9=7!*3!*3!*2!
   8 is 7!*8=7!*2!*2!*2!
   7 is 7!
   6 is 5!*6=5!*3!
   5 is 5!
   4 is 3!*4=3!*2!*2!
   3 is 3!=6
   2 is 2!=2
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const LL mod = 998244353;
const int N=2e5+10;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    vector<string> vs = {"", "", "2", "3", "322", "5", "53", "7", "7222", "7332"};
    //更换数字,很妙
    string res;
    char ch;
    for (int i = 0; i < n;i++){
        cin >> ch;
        res+=vs[ch-'0'];
    }
    sort(res.begin(), res.end(), greater<char>());//从大到小排序
    cout << res << endl;
}

Problem - 548B - Codeforces(水题)

要学会看数据范围!!计算时间复杂度,能做的直接暴力

#include <bits/stdc++.h>
using namespace std;
#define LL long long
const LL mod = 998244353;
const int N=510;
int a[N][N], res[N];
int n, m, q;

void calc(int i){
    res[i] = 0;//置零
    int cnt = 0;
    for (int j = 1; j <= m;j++){
        if(a[i][j]){
            cnt++;
        }else{
            res[i] = max(res[i], cnt);
            cnt = 0;
        }
    }
    res[i] = max(res[i], cnt);
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m >> q;
    for (int i = 1; i <= n;i++){
        for (int j = 1; j <= m;j++){
            cin >> a[i][j];
        }
        calc(i);
    }
    while(q--){
        int x, y;
        cin >> x >> y;
        a[x][y] ^= 1;
        calc(x);
        int ans = 0;
        for (int i = 1; i <= n;i++){
            ans = max(ans, res[i]);
        }
        cout << ans << endl;
    }
}

Problem - 1284B - Codeforces(upper-bound使用)

[!warning] 注意
如果遇到超int的话,尽量全开LL
LL ans = (LL)n * n;//注意,小心溢出

#include <bits/stdc++.h>
using namespace std;
#define LL long long
const LL mod = 998244353;
const int N=1e5+10;
int l[N], r[N],tag[N];
vector<int> v;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n,a;
    cin >> n;
    for (int i = 0; i < n;i++){
        int m;
        cin >> m;
        int lst = 1e9;
        for (int j = 0; j < m;j++){
            cin >> a;
            if(j==0)
                l[i] = a;
            if(j==m-1)
                r[i] = a;
            if(a>lst)
                tag[i] = 1;
            lst = a;
        }
        if(!tag[i])
            v.push_back(l[i]);
    }
    sort(v.begin(), v.end());
    LL ans = (LL)n * n;//注意,小心溢出
    for (int i = 0; i < n;i++){
        if(!tag[i]){
            ans -= upper_bound(v.begin(), v.end(), r[i]) - v.begin();
        }
    }
    cout << ans << endl;
}   

数论

Problem - 632D - Codeforces(LCM)(2100)

这题难点在

  • 从lcm考虑能选因数最大值(1e6)
  • 调和级数计算时间复杂度
    (m+m/2+m/3……+m/m)=logm
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const LL mod = 998244353;
const int N=1e6+10;
int a[N], cnt[N], res[N], vis[N];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n;i++){
        cin >> a[i];
        if(a[i]<=m)
            cnt[a[i]]++;
    }
    for (int i = 1; i <= n;i++){
        if(a[i]>m||vis[a[i]])
            continue;
        for (int j = 1; j * a[i] <= m;j++){
            res[j * a[i]] += cnt[a[i]];
        }
        vis[a[i]] = 1;
    }
    int ans = 0,lcm=1;
    for (int i = 1; i <= m;i++){
        if(ans<res[i]){
            ans = res[i];
            lcm = i;
        }
    }
    cout << lcm << " " << ans << endl;
    for (int i = 1; i <= n;i++){
        if(lcm%a[i]==0){
            cout << i << " ";
        }
    }
}

P2158 [SDOI2008] 仪仗队 - 洛谷(欧拉函数)

人被挡住,当且仅当gcd(x,y)!=1,这样会被(x/gcd,y/gcd)的人挡住
所以该题要求的是数互质的数量->欧拉函数
时间复杂度小的话用不需要用线性筛

#include <bits/stdc++.h>
using namespace std;
#define LL long long
const LL mod = 998244353;
const int N=4e4+10;
int e[N];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, ans = 2;
    cin >> n;
    if(n==1){
        cout << 0 << endl;
        return 0;
    }
    //欧拉函数埃式筛求法 O(loglogn)
    for (int i = 1; i <= n;i++){
        e[i] = i;
    }
    for (int i = 2; i <= n;i++){
        if(e[i]==i){
            for (int j = i; j <= n;j+=i){
                e[j] = e[j] / i * (i - 1);
            }
        }
    }
    for (int i = 2; i <= n - 1;i++){
        ans += e[i]*2;//对称
    }
    ans++;//(1,1)
    cout << ans << endl;
}
```<details>
<summary>点击查看代码</summary>

</details>1. 
posted @ 2025-11-06 19:07  Seren_blingbling  阅读(8)  评论(0)    收藏  举报