Educational Codeforces Round 5

Educational Codeforces Round 5

D. Longest k-Good Segment

Description

The array a with n integers is given. Let's call the sequence of one or more consecutive elements in a segment. Also let's call the segment k-good if it contains no more than kdifferent values.

Find any longest k-good segment.

Input

The first line contains two integers n, k (1 ≤ k ≤ n ≤ 5·105) — the number of elements in aand the parameter k.

The second line contains n integers ai (0 ≤ ai ≤ 106) — the elements of the array a.

output

Print two integers l, r (1 ≤ l ≤ r ≤ n) — the index of the left and the index of the right ends of some k-good longest segment. If there are several longest segments you can print any of them. The elements in a are numbered from 1 to n from left to right.

Examples

Input

5 5
1 2 3 4 5

Output

1 5

正确解法:

找只包含k个不同数字的最长序列。

每个序列都是从l到r开始的

我们从1-n开始枚举l,直到找到最长序列。若这个序列比之前记录的还要长,就保存。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <queue>
 7 #include <vector>
 8 #include <set>
 9 #include <map>
10 typedef long long ll;
11 const int N=100000+100;
12 const int mod=1e9+7;
13 using namespace std;
14 int n,k,a[5*N];
15 int now=1,cnt[1000010],nk=0;
16 int br=0,bl=0;
17 int main()
18 {
19     scanf("%d %d",&n,&k);
20     for(int i=1;i<=n;i++)
21         scanf("%d",a+i);
22     for(int i=1;i<=n;i++)
23     {
24         while((now<=n)&&((nk<k)||(nk==k&&cnt[a[now]]!=0)))
25         {
26             cnt[a[now]]++;
27             if(cnt[a[now]]==1)  nk++;
28             now++;
29         }
30         if(now-i>br-bl)
31         {
32             br=now;
33             bl=i;
34         }
35         cnt[a[i]]--;
36         if(cnt[a[i]]==0)    nk--;
37     }
38     printf("%d %d\n",bl,br-1);
39  
40     return 0;
41 }
View Code

 

E. Sum of Remainders

Description

Calculate the value of the sum: n mod 1 + n mod 2 + n mod 3 + ... + n mod m. As the result can be very large, you should print the value modulo 109 + 7 (the remainder when divided by 109 + 7).

The modulo operator a mod b stands for the remainder after dividing a by b. For example 10mod 3 = 1.

Input

The only line contains two integers n, m (1 ≤ n, m ≤ 1013) — the parameters of the sum.

output

Print integer s — the value of the required sum modulo 109 + 7.

Examples

Input

3 4

Output

4

正确解法:

若m〉n,则  n%x=n; (n<x<=m) 

我们先考虑 m<=n 的时候。

n mod 1 + n mod 2 + n mod 3 + ... + n mod m. =m*n -(n/i) *i

那我们就会知道有一段序列 其中 n/i 都是相等的。不同的就是 i 的区别。

我们只要把 1-m 按照 n/i 来划分为不同序列,序列内求和就好了。

怎么划分这个序列呢?

l=i;  r=n/(n/i)  (1<=i<=m)//可以拿具体的数验证一下

最后 i=r

--------------------------------------------------------------------------------------

n=15,m=13

[1,1]  [2,2]  [3,3]  [4,5]  [6,7]  [8,13]

--------------------------------------------------------------------------------------

当m<=n  ans=m*n-(n/i) *i ;

当m〉n  ans=n*n -(n/i) *i +(m-n)*n = m*n-(n/i) *i ;

也就是说   ans=m*n-(n/i) *i ;

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <queue>
 7 #include <vector>
 8 #include <set>
 9 #include <map>
10 typedef long long ll;
11 const int N=100000+100;
12 const int mod=1e9+7;
13 using namespace std;
14 ll a,b;
15 ll sum=0,ans=0;
16 ll mult(ll a,ll b)
17 {
18     return ((a%mod)*(b%mod))%mod;
19 }
20 int main()
21 {
22     scanf("%lld %lld",&a,&b);
23     sum=mult(a,b);
24     b=min(a,b);
25     for(ll i=1;i<=b;i++)
26     {
27         ll l=i,r=a/(a/i);
28         r=min(r,b);
29         ll cc=0;
30         if((l+r)&1) cc=mult(l+r,(r-l+1)/2);
31         else     cc=mult((l+r)/2,r-l+1);
32         ans+=mult(cc,a/i);
33         ans%=mod;
34         i=r;
35     }
36     sum-=ans;
37     if(sum<0)   sum+=mod;
38     printf("%lld\n",sum);
39 
40     return 0;
41 }
View Code

 

posted @ 2019-07-04 10:00  kaike  阅读(182)  评论(0编辑  收藏  举报