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 }
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 }