Codeforces Round #511 (Div. 1) 简要题解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35649707/article/details/82831285

传送门

Enlarge GCD

对于所有质数分开考虑,删除质数的指数最小的那几个数。

#include <bits/stdc++.h>
using namespace std;

const int RLEN=1<<18|1;
inline char nc() {
	static char ibuf[RLEN],*ib,*ob;
	(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
	return (ib==ob) ? -1 : *ib++;	
} 
inline int rd() {
	char ch=nc(); int i=0,f=1;
	while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();}
	while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
	return i*f;
}

const int N=3e5+50, L=2e7+50;
int n,pt,pr[L],npr[L],mnpr[L];

map <pair<int,int>,int> S;
typedef map <pair<int,int>,int> ::iterator it;
inline it nxt(it t) {return (++t);}
inline void sieve() {
	for(int i=2;i<L;i++) {
		if(!npr[i]) {pr[++pt]=i; mnpr[i]=i;}
		for(int j=1;j<=pt;j++) {
			long long k=1ll*i*pr[j];
			if(k>=L) break;
			npr[k]=1; 
			mnpr[k]=(i%pr[j]) ? pr[j] : mnpr[i];
			if(!(i%pr[j])) break;
		}
	}
}

int main() {
	sieve(); n=rd();
	for(int i=1;i<=n;i++) {
		int val=rd();
		while(val!=1) {
			int t=mnpr[val], c=0;
			while(!(val%t)) val/=t,  ++c;
			S[pair <int,int> (t,c)]++;
		}
	}
	int ans=n+1;
	for(it l=S.begin(),r;l!=S.end();l=r) {
		r=l; int cnt=0;
		while(r!=S.end() && r->first.first==l->first.first) {cnt+=r->second; ++r;}
		if(l!=r || (l==r && cnt!=n)) {
			int mx=(cnt==n) ? l->second : (n-cnt);
			ans=min(ans,mx);
		}
	}
	if(ans>=n) cout<<-1<<'\n';
	else cout<<ans<<'\n';
}

Little C Loves 3 II

特判一下比较小的情况,其他答案是 n m ( n m m o d &ThinSpace;&ThinSpace; 2 ) n*m - (n*m \mod 2)

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

int tr[5][5]={ {0,0,0,2,4},
			   {0,0,4,8,10},
			   {0,4,8,12,14},
			   {2,8,12,16,18},
			   {4,10,14,18,24}};
int main() {
	int n,m;
	cin>>n>>m;
	if(n<m) swap(n,m);
	long long ans=0;
	if(m==1) {
		ans+=n/6*6; n%=6;
		ans+=tr[0][n-1];
	} else if(n%4==0 || m%4==0) {
		ans=(long long)n*m;
	} else if(n%6==0 || m%6==0) {
		ans=(long long)n*m;
	} else if(n<=5 && m<=5) {
		ans=tr[n-1][m-1];
	} else {
		if(n==7 && m==2) ans=12;
		else ans=(long long)n*m/2*2;
	}
	cout<<ans<<'\n';
} 

Region Separation

显然如果固定每部分的值,划分方案是一定的。

一个值 S k \frac{S}{k} 能被划分出来当且仅当有 k \ge k 个子树 m o d &ThinSpace;&ThinSpace; S k = 0 \mod \frac{S}{k} = 0 。 一个值也能进一步划分为 S i k \frac{S}{ik}

枚举倍数,时间复杂度 O ( n log n ) O(n \log n)

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

const int RLEN=1<<18|1;
inline char nc() {
	static char ibuf[RLEN],*ib,*ob;
	(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
	return (ib==ob) ? -1 : *ib++;
} 
inline int rd() {
	char ch=nc(); int i=0,f=1;
	while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();}
	while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
	return i*f;
}

const int N=1e6+50, mod=1e9+7;
inline void add(int &x,int y) {x=(x+y>=mod) ? (x+y-mod) : (x+y);}

int n,p[N],g[N],f[N];
LL a[N];

int main() {
	n=rd();
	for(int i=1;i<=n;i++) a[i]=rd();
	for(int i=2;i<=n;i++) p[i]=rd();
	for(int i=n;i>1;i--) a[p[i]]+=a[i];
	for(int i=1;i<=n;i++) {
		LL t=a[1]/__gcd(a[1],a[i]);
		if(t<=n) ++g[t];
	}
	for(int i=n;i>=1;i--) for(int j=2*i;j<=n;j+=i) g[j]+=g[i];
	for(int i=n;i>=1;i--) if(g[i]>=i) {
		f[i]=1;
		for(int j=2*i;j<=n;j+=i) add(f[i],f[j]);
	}
	cout<<f[1]<<'\n';
}

Intervals of Intervals

对于每个 r r 处理出每个 l l 的答案(差分后只有 O ( n ) O(n) )个。 然后二分第 k k O ( n ) O(n) 检查即可。 时间复杂度 O ( n log n ) O(n \log n)

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef map <int,int> ::iterator it_m;
typedef pair <int,int> pii;
typedef pair <LL,LL> pLL;
#define X first
#define Y second

const int RLEN=1<<18|1;
inline char nc() {
	static char ibuf[RLEN],*ib,*ob;
	(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
	return (ib==ob) ? -1 : *ib++;
} 
inline int rd() {
	char ch=nc(); int i=0,f=1;
	while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();}
	while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
	return i*f;
}

const int N=3e5+50;
int n,k,a[N],b[N],d[N],val[N];
vector <pii> det[N];
map <int,int> s;

inline it_m nxt(it_m it) {return ++it;}
inline void split(int p) {
	it_m it=--s.upper_bound(p);
	if(it->X!=p) s[p]=it->Y;
}
inline pLL check(int v) {
	for(int i=1;i<=n+1;i++) d[i]=0; 
	LL cnt=0, sum=0;
	LL nowc=0, nows=0;
	for(int r=1,l=1;r<=n;++r) {
		for(auto j:det[r]) {
			d[j.X]+=j.Y;
			if(j.X<=l) nowc+=j.Y, nows+=(LL)(l-j.X)*j.Y;
		}
		while(nowc>v) {
			nows+=nowc;
			nowc+=d[++l];
		}
		cnt+=(l-1); sum+=nows;
	}
	return pLL(cnt,sum);
} 

int main() {	
	n=rd(), k=rd();
	s[0]=0; s[1e9+1]=0;
	for(int i=1;i<=n;i++) {
		int l=rd()+1, r=rd();
		a[i]=l; b[i]=r;
		split(l); split(r+1);
		for(it_m it=s.lower_bound(l);it->first<=r;) {
			it_m tp=nxt(it);
			det[i].push_back(pii(it->Y+1,nxt(it)->X-it->X));
			s.erase(it); it=tp;
		}  det[i].push_back(pii(i+1,-(r-l+1)));
		s[l]=i;
	}
	int l=0, r=1e9, lst; 
	pLL ans;
	while(l<=r) {
		int mid=(l+r)>>1;
		pLL t=check(mid);
		if(t.X<k) lst=mid, ans=t, r=mid-1;
		else l=mid+1;
	}
	cout<<ans.Y+(LL)(k-ans.X)*lst;
}

Little C Loves 3 III

我们可以把 a i a_i 表示为 a i p x a_i p^x 的形式,然后只需要fmt后求 c i p x m o d &ThinSpace;&ThinSpace; p \frac{c_i}{p^x} \mod p

注意到 p = 2 2 p=2^2 ,直接用64位整数运算即可。

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;

const int RLEN=2<<18|1;
inline char nc() {
	static char ibuf[RLEN],*ib,*ob;
	(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
	return (ib==ob) ? -1 : *ib++;
} 
inline int rd() {
	char ch=nc(); int i=0,f=1;
	while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();}
	while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
	return i*f;
}

const int N=(1<<21)+50;
int n,m;
char A[N],B[N];
ULL a[N],b[N];
#define bc __builtin_popcount

inline void fmt(ULL *t) {
	for(int i=1;i<m;i<<=1)
		for(int j=0;j<m;j++) if(i&j) 
			t[j]+=t[i^j];
}
inline void dfmt(ULL *t) {
	for(int i=1;i<m;i<<=1)
		for(int j=0;j<m;j++) if(i&j)
			t[j]-=t[i^j];
}
int main() {
	scanf("%d%s%s",&n,A,B);
	m=1<<n;
	for(int i=0;i<m;i++) a[i]=(A[i]-'0')*(1ull<<(2*bc(i))), b[i]=(B[i]-'0')*(1ull<<(2*bc(i)));
	fmt(a); fmt(b);
	for(int i=0;i<m;i++) b[i]=a[i]*b[i];
	dfmt(b);
	for(int i=0;i<m;i++) putchar('0'+((b[i]>>(2*bc(i)))&3));
}

猜你喜欢

转载自blog.csdn.net/qq_35649707/article/details/82831285