AT2300题解

两种做法都说一说吧。。。

题意很明确。

1.数论分块

对于一个 \(d\) 和给定的 \((l,r)\)\((l,r)\) 对其造成贡献的条件很明显是 \(\lfloor \frac {l-1} d \rfloor \ne \lfloor \frac r d \rfloor\)

然后一个数论分块就没了。

只跑了 4s 还是挺离谱的,应该吊打了大部分数论分块。

#include<cstdio>
#include<cctype>
typedef unsigned ui;
const ui M=1e5+5;
ui n,m,s[M];double inv[M];
inline void write(ui n){
	static char s[10];ui top(0);while(s[++top]=n%10^48,n/=10);while(putchar(s[top--]),top);
}
inline ui read(){
	ui n(0);char s;while(!isdigit(s=getchar()));while(n=n*10+(s&15),isdigit(s=getchar()));return n;
}
inline ui min(const ui&a,const ui&b){
	return a>b?b:a;
}
signed main(){
	ui i,L,R,l,r,x,y;m=read();n=read();
	for(i=1;i<=n;++i)inv[i]=1./i+1e-15;
	while(m--){
		l=read()-1;r=read();
		for(L=1;L*L<=r&&L<=l;++L)if(ui(l*inv[L])^ui(r*inv[L]))++s[L],--s[L+1];
		for(x=l*inv[L],y=r*inv[L];L<=l;L=R+1){
			if(x*L>l)--x;if(y*L>r)--y;R=min(ui(l*inv[x]),ui(r*inv[y]));
			if(x^y)++s[L],--s[R+1];
		}
		++s[l+1];--s[r+1];
	}
	for(i=1;i<=n;++i)write(s[i]+=s[i-1]),putchar(10);
}

2.树状数组

只能说这个数据分类实在是太妙了 Orz

数据分类。

  1. 区间长度不小于 \(d\)

贡献很明显是 \(1\)

  1. 区间长度小于 \(d\)

我们直接对这些区间进行区间修改,然后直接查询 \(d\) 的倍数,每个区间只可能对答案贡献最多一次。

#include<algorithm>
#include<cstdio>
#include<cctype>
typedef unsigned ui;
const ui M=1e5+5;
ui n,m,s[M],CB[M],id[M*3],l[M*3],r[M*3],d[M*3],BIT[M*3];double inv[M];
inline void write(ui n){
	static char s[10];ui top(0);while(s[++top]=n%10^48,n/=10);while(putchar(s[top--]),top);
}
inline ui read(){
	ui n(0);char s;while(!isdigit(s=getchar()));while(n=n*10+(s&15),isdigit(s=getchar()));return n;
}
inline void Add(ui x,const ui&val){
	while(x<=n)BIT[x]+=val,x+=x&-x;
}
inline ui Query(ui x){
	ui ans(0);
	while(x>=1)ans+=BIT[x],x^=x&-x;
	return ans;
}
signed main(){
	ui i,j,ans,now;m=read();n=read();now=m;
	for(i=1;i<=m;++i)l[i]=read(),r[i]=read(),++CB[d[i]=r[i]-l[i]+1],id[i]=i;
	for(i=n;i>=1;--i)CB[i]+=CB[i+1];for(i=m;i>=1;--i)id[CB[d[i]]--]=i;
	for(i=1;i<=n;++i){
		while(d[id[now]]<i&&now)Add(l[id[now]],1),Add(r[id[now]]+1,-1),--now;ans=now;
		for(j=i;j<=n;j+=i)ans+=Query(j);write(ans);putchar(10);
	}
}

成功杀到最优解。

posted @ 2022-01-11 14:56  Prean  阅读(25)  评论(0编辑  收藏  举报
var canShowAdsense=function(){return !!0};