2018暑假牛客多校第六场

A-Singing Contest

就是两个两个比较,然后用比对手大的最小的去与对手比就行了~

#include"bits/stdc++.h"
#define out(x) cout<<#x<<"="<<x
#define C(n,m) ((long long)fac[(n)]*inv[(m)]%MOD*inv[(n)-(m)]%MOD)
using namespace std;
typedef long long LL;
const int maxn=(1<<16)+5;
const int MOD=1e9+7;
int N,cnt;
struct AAA
{
    int id;
    vector<int>v;
};
AAA a[maxn];
void pushup(int id)
{
    int n=a[id<<1].v.size()-1;
    if(a[id<<1].v[n]<a[id<<1|1].v[n])swap(a[id<<1],a[id<<1|1]);
    int i=n;
    while(a[id<<1].v[i]>a[id<<1|1].v[n])i--;
    a[id<<1].v.erase(a[id<<1].v.begin()+i+1);
    a[id]=a[id<<1];
}
void Build(int id,int L,int R)
{

    if(L==R)
    {
        a[id].id=++cnt;
        for(int j=1;j<=N;j++)
        {
            int t;
            scanf("%d",&t);
            a[id].v.push_back(t);
        }
        sort(a[id].v.begin(),a[id].v.end());
        return ;
    }
    int mid=L+R>>1;
    Build(id<<1,L,mid);
    Build(id<<1|1,mid+1,R);
    pushup(id);
}
int main()
{
    int T;
    scanf("%d",&T);
    for(int Case=1;Case<=T;Case++)
    {
        memset(a,0,sizeof a);
        cnt=0;
        scanf("%d",&N);
        Build(1,1,(1<<N));
        cout<<"Case #"<<Case<<": "<<a[1].id<<endl;
    }
}

J-Heritage of skywalkert

这道题也没懂他啥意思,据说反正就是求出前面几个最大的然后暴力求 lcm l c m 就行了,但是看大佬的写法学到一个新的 stl s t l 里的函数,

nth_element(a+1,a+1+K,a+1+N) n t h _ e l e m e n t ( a + 1 , a + 1 + K , a + 1 + N )

就是用来找 1N 1 到 N 里第 K K 个小的元素,并且把比他小的放到左边,大的放到右边,据说是 O(n) 的复杂度~

#include"bits/stdc++.h"
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uint;
const int maxn=1e7+5;
const int MOD=1e9+7;
ull a[maxn];
unsigned int X,Y,Z;
ull tang()
{
    X^=X<<16;
    X^=X>>5;
    X^=X<<1;
    ull t=X;
    X=Y;
    Y=Z;
    Z=t^X^Y;
    return Z;
}
ull gcd(ull a,ull b)
{
    if(b==0)return a;
    else return gcd(b,a%b);
}
ull lcm(ull a,ull b)
{
    ull t=a/gcd(a,b);
    return t*b;
}
int main()
{
    int T;
    scanf("%d",&T);
    uint N,A,B,C;
    for(int Case=1;Case<=T;Case++)
    {
        cin>>N>>A>>B>>C;
        X=A,Y=B,Z=C;
        for(int i=1;i<=N;i++)a[i]=tang();
        int K=max(0,(int)N-200);
        nth_element(a+1,a+1+K,a+1+N);//就是这个函数
        ull Max=0;
        for(int i=K+1;i<=N;i++)
        {
            for(int j=i+1;j<=N;j++)
            {
                Max=max(Max,lcm(a[i],a[j]));
            }
        }
        cout<<"Case #"<<Case<<": "<<Max<<endl;
    }
}
网在 2018 年举办的 ACM 暑期训练营是一系列面向算法竞赛爱好者的在线编程赛事,旨在帮助参赛者提升算法能力、团队协作能力以及对复杂问题的解决能力。比赛通常以团队为单位参与,每场比赛包含若干道编程题目,涉及图论、数据结构、动态规划、字符串等个算法领域。 ### 比赛题目与题型分布 比赛题目通常由个高或企业出题,涵盖难度从简单到困难的题目,例如: - **数学与数论**:包括模运算、素数判定、数列处理等。 - **图论**:涉及最短路径(Dijkstra、Floyd)、最小生成树(Kruskal、Prim)、拓扑排序等。 - **动态规划**:包括线性DP、区间DP、树形DP等。 - **字符串处理**:KMP、AC自动机、后缀数组等。 - **数据结构**:线段树、并查集、平衡树等。 - **组合数学与计算几何**:排列组合、概率期望、凸包等。 例如,在第六场的 G 题中,涉及树的性质和图论的网络流问题,需要计算所有点对之间的最大流之和,这要求对树上路径性质有深入理解[^1]。 ### 题解与解题思路 每场比赛结束后,网通常会发布官方题解,并鼓励选手在论坛或博中分享解题思路和代码。例如: - 在第四场的 G 题中,题目要求找出删除若干元素后使得众数唯一的问题。题解中提出从大到小枚举可能的众数候选,并判断是否可以通过删除不超过 M 个元素来实现目标。此题需要注意内存初始化的问题,因为 T 的范围未知,常规的 `memset` 可能导致超时,因此建议使用 `map` 或其他结构进行优化[^4]。 - 在第一场的 J 题中,使用了将数组扩展为两倍长度的技巧,以便处理环形数组问题,这种技巧在处理循环数组时非常常见且有效[^3]。 ### 比赛经验分享 参赛者通常会从以下几个方面总结经验: - **时间管理**:比赛通常为 3-5 小时,合理分配时间解出尽可能的题目是关键。 - **团队协作**:三人组队时,分工明确(如一人主写代码,一人读题,一人调试)能显著提高效率。 - **模板积累**:熟练掌握常用算法模板(如快速幂、Dijkstra、线段树等)可大幅节省编码时间。 - **调试技巧**:使用断点调试、对拍工具等能快速发现代码中的错误。 - **赛后复盘**:分析未通过的题目,理解官方题解并尝试重新实现是提升的关键。 ### 示例代码 以下是一个用于处理二维字符矩阵对称性的代码片段,来自第四场 D 题的解法: ```cpp #include <bits/stdc++.h> using namespace std; const int maxN = 2000 + 5; int n, m; char str[maxN][maxN]; int main() { int T; scanf("%d", &T); while (T--) { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf("%s", str[i] + 1); int tp = -1; for (int i = 1; i <= n / 2; i++) { bool f = true; for (int j = 1; j <= m; j++) if (str[i][j] != str[n - i + 1][j]) { f = false; break; } if (!f) { tp = i; break; } } if (tp == -1) tp = n / 2; int tq = -1; for (int j = 1; j <= m / 2; j++) { bool f = true; for (int i = 1; i <= n; i++) if (str[i][j] != str[i][m - j + 1]) { f = false; break; } if (!f) { tq = j; break; } } if (tq == -1) tq = m / 2; int ans; if (tp == 1 || tq == 1) { ans = 0; } else { ans = (tp - 1) * (tq - 1); } printf("%d\n", ans); } return 0; } ``` 该代码通过逐行逐列判断矩阵的对称性,最终计算出可以保留的对称区域数量。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值