D

滑动窗口
用vis标记…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include<bits/stdc++.h>
using namespace std;

const int maxn = 5e5 + 10;
int a[maxn];
int vis[2*maxn];

int main()
{
//freopen("test.txt","r",stdin);
int n,k;
scanf("%d %d",&n,&k);
for(int i=0;i<n;++i) scanf("%d",a+i);
int i,j,cur = 0,ans = 0,end = 0;
i = j = 0;
memset(vis,0,sizeof vis);
while(j<n)
{
if(!vis[a[j]]) ++cur;
++vis[a[j]];
//printf("%d\n",cur);
while(cur>k)
{
--vis[a[i]];
if(!vis[a[i]]) --cur;
++i;
}
//printf("%d %d\n",i,j);
if(j-i+1 > ans)
{
ans = j-i+1;
end = j;
}
++j;
}
printf("%d %d\n",end-ans+2,end+1);
return 0;
}

E

数论
推公式,最后分块求

注意会爆long long 要不断模…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod = 1e9 + 7;

LL pow_mod(LL a,int n)
{
LL res = 1;
while(n)
{
if(n&1) res = (res*a) %mod;
a = a*a %mod ;
n>>=1;
}
return res;
}

int main()
{
//freopen("test.txt","r",stdin);
LL n,m;
scanf("%lld %lld",&n,&m);
LL inv = pow_mod(2,mod-2);
// printf("%lld\n",inv);
LL ans = (n%mod)*(m%mod)%mod,dec = 0,l=1,r;
m = min(n,m);
while(l<=m)
{
r = min(m,n/(n/l));
dec += ((n/l)%mod) * ((r+l)%mod)%mod *((r-l+1)%mod) %mod * inv %mod;
dec %= mod;
l = r+1;
}
ans += mod - dec;
ans %= mod;
printf("%lld\n",ans);
return 0;
}