51Nod——T 1686 第K大区间

https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1686

基准时间限制:1 秒 空间限制:131072 KB 分值: 40  难度:4级算法题
 收藏
 关注

定义一个区间的值为其众数出现的次数
现给出n个数,求将所有区间的值排序后,第K大的值为多少。

 

众数(统计学/数学名词)_百度百科 

Input
第一行两个数n和k(1<=n<=100000,k<=n*(n-1)/2)
第二行n个数,0<=每个数<2^31
Output
一个数表示答案。
Input示例
4 2
1 2 3 2
Output示例
2



二分区间的值 x (logn)
枚举一个右端点,记录[l,r]之间每个数的出现个数(离散化,map统计)
如果一个数在[l,r]中的出现个数>=x,则 当 r 属于[r+1,n] 中时,同样满足
满足时,不断缩小l,判断每个区间的情况 (o(n))
nlogn
 1 #include <algorithm>
 2 #include <cstring>
 3 #include <cstdio>
 4 
 5 inline void read(int &x)
 6 {
 7     x=0; register char ch=getchar();
 8     for(; ch>'9'||ch<'0'; ) ch=getchar();
 9     for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
10 }
11 
12 const int N(100005);
13 int n,k,b[N];
14 
15 struct Node {
16     int num,id;
17     bool operator < (const Node&x)const
18     {
19         return num<x.num;
20     }
21 }a[N];
22 
23 int L,R,Mid,ans,cnt[N];
24 inline bool check(int x)
25 {
26     memset(cnt,0,sizeof(cnt));
27     int l=1,r=1,ret=0;
28     for(; r<=n; ++r)
29     {
30         cnt[b[r]]++;
31         if(cnt[b[r]]>=x)
32         {
33             ret+=n-r+1;
34             cnt[b[l++]]--;
35             for(; cnt[b[r]]>=x&&l<r; )
36             {
37                 ret+=n-r+1;
38                 cnt[b[l++]]--;
39             }
40         }
41         if(ret>=k) return 1;
42     }
43     return 0;
44 }
45 
46 int Presist()
47 {
48     read(n),read(k);
49     for(int i=1; i<=n; ++i)    read(a[i].num),a[i].id=i;
50     std::sort(a+1,a+n+1);
51     for(int i=1; i<=n; ++i)
52         b[a[i].id]=(a[i].num!=a[i-1].num)?++a[0].id:a[0].id;
53     for(L=0,R=n; L<=R; )
54     {
55         Mid=L+R>>1;
56         if(check(Mid))
57         {
58             ans=Mid;
59             L=Mid+1;
60         }
61         else R=Mid-1;
62     }
63     printf("%d",ans);
64     return 0;
65 }
66 
67 int Aptal=Presist();
68 int main(int argc,char**argv){;}

 

转载于:https://www.cnblogs.com/Shy-key/p/7672481.html

### 关于51Nod平台上编号为1020的问题详情与解答 #### 问题描述 在51Nod平台上的第1020号问题是关于计算两个整数相加的结果[^1]。给定两个正整数A和B,长度不超过10^6位,要求编写程序来求解这两个数的和。 #### 输入格式说明 输入数据由多组测试案例组成;每组测试案例占两行,分别表示要相加的整数A和B。对于每一组测试案例,应当单独输出一行结果,即A+B的值。 #### 解决方案概述 解决此问题的关键在于处理超数据类型的运算,在多数编程语言中内置的数据类型无法直接支持如此规模数值的操作。因此,可以采用字符串的方式来存储这些整数,并实现逐位相加逻辑,同时考虑进位情况。 下面是一个Python版本的具体实现方法: ```python def add_large_numbers(a: str, b: str) -> str: # Reverse strings to make addition easier from least significant digit a = a[::-1] b = b[::-1] carry = 0 result = [] max_length = max(len(a), len(b)) for i in range(max_length): digit_a = int(a[i]) if i < len(a) else 0 digit_b = int(b[i]) if i < len(b) else 0 total = digit_a + digit_b + carry carry = total // 10 current_digit = total % 10 result.append(str(current_digit)) if carry != 0: result.append(str(carry)) return ''.join(reversed(result)) if __name__ == "__main__": while True: try: num1 = input().strip() num2 = input().strip() print(add_large_numbers(num1, num2)) except EOFError: break ``` 该代码片段定义了一个函数`add_large_numbers`用于接收两个作为参数传入的整数(形式上为字符串),并返回它们之和同样作为一个字符串。通过反转输入字符串使得最低有效位位于索引位置0处从而简化了按位累加的过程。最后再将得到的结果列表反向拼接成最终答案输出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值