智灵班 2025 春季普及+期中测试总结

前言:写这玩意是真费手啊!!:face_with_spiral_eyes:

T1 增加模数

  • 题目大意:给定H对(Ai,Bi)和 M。计算(A1^B1+A2^B2+…+AH^BH)mod M的值。

  • 大体思路:根据时间限制和数据范围初步判断,可以快速幂直接计算。这里需要注意单独考虑A=0&&B=0的情况 。不知道不开long long会不会见祖宗,反正开了肯定错不了!:blush:

  • 核心代码(快速幂函数):

    long long r=1%m;  
    a=a%m;
    while(b>0){
        if(b%2==1) r=(r*a)%m;
        a=(a*a)%m;
        b=b/2;
    }
    return r;

T2 人工降雨:

  • 题目大意:
    download
    如果一个位置能被雨淋到,而且紧挨着的旁边的建筑不高于他,那么旁边的建筑也能被雨淋到。问最多能淋到雨的位置有几个。

  • 大体思路:看这个1e3的数据量,直接暴力水过去就行了。遍历每个点,循环模拟一下,看最多能淋到几个建筑。最后取个max。看到这题我的第一反应竟然是最长上升子序列!现在想一想当一定是疯了。。。。。。

  • 核心代码:

    for(int i=0;i<n;i++) {
        int sum=1; 
        for(int j=i-1;j>=0;j--) {
            if (h[j]<=h[j+1]) sum++;
			else  break;
        }//向左遍历
        for (int j=i+1;j<n;j++) {
            if(h[j]<=h[j-1]) sum++;
            else break;
        }//向右遍历
        if(sum>Max) Max=sum;//记录最大值
    }

T3 Static Range Minimum Queries:

  • 题目大意:
    给定一个由n个整数组成的数组,你的任务是处理q个查询,查询形式为:在范围[a,b]中的最小值是多少?

  • 大体思路:对于这个问题,我们需要高效处理大量区间最小值查询(RMQ)。考虑到数据范围(n和q都可能达到2×10^5),我们需要使用时间复杂度为O(n log n)预处理和O(1)每查询的算法,不出意外的话应该是ST表。

  • 核心代码:

   void ST() {
    for(int i=0;i<n;i++) b[i][0]=a[i];
    for(int j=1;(1<<j)<=n;j++) for(int i=0;i+(1<<j)-1<n;i++) b[i][j]=min(b[i][j-1],b[i+(1<<(j-1))][j-1]);
}//ST表,我就不多说什么了 

T4 Meet in the Middle:

  • 题目大意:
    给定 n 和一个长度为 n 的数组,有多少种方法选择一个该数组的子集使得和为 x 。

  • 大体思路:双向搜索模板题。
    将数组分成两半,对前一半进行搜索并存储结果,然后搜索后一半并计算前一半中与其匹配的结果总数。

  • 核心代码:

  void s1(const vector<int>& nums,int start,int end,vector<long long>& sums,long long sum1=0) {
    if (start > end) {
        sums.push_back(sum1);
        return;
    }
    s1(nums,start+1,end,sums,sum1+nums[start]);
    s1(nums,start+1,end,sums,sum1);
}
long long s2(const vector<int>&nums,int x){
    int n = nums.size();
    int mid = n / 2;
    vector<long long>sum2, sum3;
    s1(nums,0,mid-1,sum2);
    s1(nums,mid,n-1,sum3);
    unordered_map<long long, long long> R;
    for (long long sum : sum3)  R[sum]++;
    long long count = 0;
    for (long long sum : sum2){
        long long y=x-sum;
        if (R.find(y)!=R.end()) count+=R[y];
    }
    return count;
}

T5 Bovine Genomics:

  • 题目大意:
    奶牛的斑点不仅可以通过基因组中的一个或两个位置解释,还可以通过观察三个不同的位置集合来解释。请帮助他计算能够解释斑点的三个不同位置集合的数量。

  • 大体思路:
    这个问题要求我们找出所有可能的三元位置组合(i,j,k),使得在这些位置上,斑点奶牛和无斑点奶牛的基因序列没有重叠。也就是说,对于任何斑点奶牛和无斑点奶牛,它们在这三个位置上的基因组合应该是不同的。

  • 核心代码:

for (const string &p : pl) {
       string key;
       key += p[i];
       key += p[j];
       key += p[k];
       if (spz.count(key)) {
           valid = false;
            break;
        }
       //枚举三种基因的排列情况
  }
  if (valid) ++count;//符合题目要求,总数加一

T6 盛宴:

  • 题目大意:
    找出满足条件的连续食材区间,使得:
    • 总香味值 ≥ M;
    • 在所有满足条件的方案中,最大辣度尽可能小。

  • 大体思路:
    先二分查找,用来确定最小的尺寸上限,通过不断缩小范围来找到最优解。滑动窗口用来判断在给定的尺寸上限下,是否存在一种合法的方案,使得总费用不超过 m。

  • 核心代码:

while (sum >= M) {
    ll max_S = S[q.front()];
    if (max_S < min_max_S) {
        min_max_S = max_S;
    }
    sum -= F[left];
    if (q.front() == left) {
        q.pop_front();
     }
     left++;
 }

T8 邦布照相:

  • 题目大意:
    给定平面上N个点,找出其中的一对点的距离,使得在这N个点的所有点的对中,该距离为所有点对中最小的。(2<=n<50000)

  • 大体思路:
    遍历邦布型号的序列 ,我们对于这个 x 中的每个元素都检查一下他在不在栈里已经出现过,如果出现过的话就直接跳过这个元素进入下一个元素。
    还有为了保证答案字典序最小,我们如果当前这个元素大于栈顶的元素的时候,我们就把栈顶元素弹出然后把哈希表里的这个元素也要移除。最后输出。

  • 核心代码:

for(int i=0;i<n;i++){
       if(该元素已经被加入){
            跳过
        }
        while(如果当前元素小于栈顶并且后面还会出现栈顶所代表的元素){
            删除栈顶,删除哈希表中所代表的元素
        }
        元素入栈,存入哈希表
    }
2 个赞

where’s T7

T2我比你更离谱,一开始想到的是深搜,而且就是用深搜写的!而且没超时!!!!!
@杨瑞
可以看 这里

1 个赞

谢谢指正!接下来请听我狡辩:可以看出,我每道题的总结大纲都是复制的上一题。当时直接把真正的T7当成刚复制的“模版”给改造成了T8 :smiling_face_with_tear:

有实力