社区讨论

样例没过,但A了,求调

P1494[国家集训队] 小 Z 的袜子参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@m52hpp7t
此快照首次捕获于
2024/12/24 21:16
去年
此快照最后确认于
2025/11/04 12:23
4 个月前
查看原帖
CPP
#include <bits/stdc++.h>
using namespace std;
const int N = 5e4+5,M = 301;
int n,m; int c[N]; int L;
int id[N];
int cnt[N];
long long h[N];
long long f[M][M],g[M][N];
int read(){
	int x=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9')ch=getchar();
	while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
void write(long long x){
	if(x>9) write(x/10);
	putchar(x%10+'0');
}
long long gcd(long long a,long long b){
	return b>0 ? gcd(b,a%b) : a;
}
void qry(int l,int r){
	if(r-l+1==1){
		putchar('0'),putchar('/'),putchar('1'),putchar('\n');
		return;
	}
	int li=id[l],ri=id[r];
	long long res = 0;
	if(li==ri){
		for(register int i=l;i<=r;++i){
			cnt[c[i]]++;
		}
		for(register int i=l;i<=(li*L);++i){
			int j=c[i];
			res+=h[cnt[j]];
			cnt[j]=0;
		}
	}
	else{
		res=f[li+1][ri-1];
		for(register int i=l;i<=(li*L);++i){
			cnt[c[i]]++;
		}
		for(register int i=(ri-1)*L+1;i<=r;++i){
			cnt[c[i]]++;
		}
		for(register int i=l;i<=(li*L);++i){
			int j=c[i];
			if(cnt[j]){
				res-=h[g[ri-1][j]-g[li][j]];
				res+=h[g[ri-1][j]-g[li][j]+cnt[j]];
				cnt[j]=0;
			}
		}
		for(register int i=(ri-1)*L+1;i<=r;++i){
			int j=c[i];
			if(cnt[j]){
				res-=h[g[ri-1][j]-g[li][j]];
				res+=h[g[ri-1][j]-g[li][j]+cnt[j]];
				cnt[j]=0;
			}
		}
	}
	long long gd = gcd(res,h[r-l+1]);
	write(res/gd),putchar('/'),write(h[r-l+1]/gd),putchar('\n');
}
signed main(){
	n=read(),m=read();
	L = sqrt(n)-21;
	for(register int i=1;i<=n;++i){
		c[i]=read();
		id[i] = (i-1)/L+1;
	} 
	for(register int i=1;i<=n;++i){
		h[i]=(long long)i*(i-1)/2;
	}
	for(register int i=1;i<=id[n];++i){
		int j = L*(i-1)+1;
		while(id[j]==i){
			cnt[c[j]]++;
			j++;
		}
		for(j=1;j<=n;++j) g[i][j]=cnt[j];
	}
	for(register int i=1;i<=n;++i) cnt[i]=0;
	long long now=0;
	for(register int l=1;l<=id[n];++l){
		if(l&1){
			int j = L*(l-1)+1;
			while(id[j]==l){
				now-=h[cnt[c[j]]];
				cnt[c[j]]++;
				now+=h[cnt[c[j]]];
				j++;
			}
			f[1][l]=now;
			for(register int i=1;i+l<=id[n];++i){			
				int j = L*(i-1)+1;
				while(id[j]==i){
					now-=h[cnt[c[j]]];
					cnt[c[j]]--;
					now+=h[cnt[c[j]]];
					j++;
				}
				j = L*(i+l-1)+1;
				while(id[j]==i+l){
					now-=h[cnt[c[j]]];
					cnt[c[j]]++;
					now+=h[cnt[c[j]]];
					j++;
				}
				f[i+1][i+l]=now;
			}					
		}
		else{
			int j = L*(id[n]-l+1-1)+1;
			while(id[j]==id[n]-l+1){
				now-=h[cnt[c[j]]];
				cnt[c[j]]++;
				now+=h[cnt[c[j]]];
				j++;
			}
			f[id[n]-l+1][id[n]]=now;
			for(register int i=id[n];i-l>=1;--i){			
				int j = L*(i-1)+1;
				while(id[j]==i){
					now-=h[cnt[c[j]]];
					cnt[c[j]]--;
					now+=h[cnt[c[j]]];
					j++;
				}
				j = L*(i-l-1)+1;
				while(id[j]==i-l){
					now-=h[cnt[c[j]]];
					cnt[c[j]]++;
					now+=h[cnt[c[j]]];
					j++;
				}
				f[i-l][i-1]=now;
			}			
		}
	}
	for(register int i=1;i<=n;++i) cnt[i]=0;
	for(register int i=1;i<=m;++i){
		int l,r; l=read(),r=read();
		qry(l,r);
	}
} 

回复

1 条回复,欢迎继续交流。

正在加载回复...