AcWing - 2016 年清华大学计算机系推研 - 1327. 魔法学校

这篇博客介绍了AcWing上的一道题目,涉及魔法学校中短信发送的问题。博主探讨了如何找出在指定天数范围内收到短信最多的学生,并给出了不同的解题思路,包括使用差分数组结合离线莫队、在线莫队、记忆化等方法,但遇到了超时和段错误等问题。
摘要由CSDN通过智能技术生成

在一所魔法学校中,有许多的学生,每个学生有一个学号(从 1 开始,用连续的正整数编号)。

每天,这所学校的校长会向一些学生发送一条短信(具体来说,在第 i 天,校长会向学号在区间 [Li,Ri] 内的学生发送一条短信,每天的 Li 和 Ri 可能不同);从第 1 天开始,一共持续 n 天。

现在,学校的教导主任想要知道,在第 Ai 天到第 Bi 天(包含第 Ai 天和第 Bi 天),哪个学生收到的短信数量最多,最多数量是多少。

由于教导主任太忙了,所以现在麻烦你帮他找到答案。

输入格式
输入文件第一行一个正整数 n,表示校长连续 n 天向学生发送短信。

接下来 n 行,每行两个正整数 Li,Ri,表示第 i 天校长向学号在区间 [Li,Ri] 内的同学发一条短信。

接下来一行一个正整数 m,表示教导主任有 m 个询问。

接下来 m 行,每行两个正整数 Ai,Bi,表示询问第 Ai 天到第 Bi 天(包含第 Ai 天和第 Bi 天),哪个学生收到的短信数量最多,最多数量是多少。

输出格式
输出文件共 m 行,每行输出空格隔开的两个正整数表示对应的教导主任询问的答案。

每行的第一个数表示收到最多短信的学生的学号,如果有多个学生均收到了最多数量的短信,你只需要输出他们之中最小的学号。

每行的第二个数表示该学生在第 Ai 天到第 Bi 天(包含第 Ai 天和第 Bi 天)一共收到了多少条短信。

数据范围
对于30%的数据,1≤n≤5×102,1≤Li≤Ri≤5×102,1≤m≤5×102
对于70%的数据,1≤n≤5×103,1≤Li≤Ri≤5×103,1≤m≤5×103
对于100%的数据,1≤n≤5×104,1≤Li≤Ri≤5×104,1≤m≤5×104,1≤Ai≤Bi≤n
输入样例:
5
1 5
1 3
3 5
2 2
4 10
3
1 1
1 3
3 4
输出样例:
1 1
3 3
2 1

新人刚学c一个多月 把自己写这个题的过程都记录在这了 (从下往上) 希望对大家能有所帮助

//差分数组 + 离线莫队 分块 奇偶优化(每块排序方向来回颠倒 减少右侧下标移动的距离)

#include <stdio.h>
#include <string.h>
#include <math.h>
#define numMAX 50000                                //本题天数 学生数
typedef struct block{
    int cal;                                        //查询顺序
    int begDate;                                    //查询起始天数
    int endDate;                                    //查询结束天数
}block;
void quicksort(block a[],int lo,int hi,int order);  //快排 order==0为增序 1为降序
int main(){
    //n为天数 m为查询次数 i j k循环 c d p q t暂存
    //stu记录学生在某些天 收到信息次数 gap为stu的差分数组 max s暂存每次查询的结果
    int n,m,i,j,k,c,d,p,q,t,stu[numMAX+1],gap[numMAX+1],max=0,s;
    memset(stu,0,sizeof(stu));                      //初始化
    memset(gap,0,sizeof(gap));

scanf("%d",&n);
int send[n+1][2];                               //记录1~n天 发送信息的学生编号区间
for(i=1;i<=n;i++){
	scanf("%d %d",&send[i][0],&send[i][1]);
	if(send[i][0]>max) max=send[i][0];          //max此处暂存一下 区间左端点的最大值
}

int numblock=sqrt(max);                         //分块数(用max来做 有时会小一些)

gap[send[1][0]]++;                              //初始化p q
if(send[1][1]<numMAX) gap[send[1][1]+1]--;
p=q=1;

scanf("%
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值