ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

BZOJ多校Day4

2021-09-25 20:01:30  阅读:172  来源: 互联网

标签:dep fx fy Day4 多校 fa int include BZOJ


A

枚举每个 \(a_i\) 的因数即可。\(\mathcal O(n\sqrt{a_i})\)。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
#include<ctime>
#include<cstdlib>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned long long ull;
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	return x*f;
}	
map<int,int> cnt;
const int N=210;
int a[N],ans[N];
int main()
{
	freopen("divisors.in","r",stdin);
	freopen("divisors.out","w",stdout);
	int n=read(),m=read();
	for(int i=1;i<=m;i++)a[i]=read();
	for(int i=1;i<=m;i++)
	{
		for(int j=1;j*j<=a[i];j++)
		{
			if(a[i]%j)continue;
			if(j<=n)cnt[j]++;
			if(j*j!=a[i]&&a[i]/j<=n)cnt[a[i]/j]++;
		}
	}
	int Ans=n;
	for(map<int,int>::iterator it=cnt.begin();it!=cnt.end();it++)ans[it->second]++,Ans--;
	printf("%d\n",Ans);
	for(int i=1;i<=m;i++)printf("%d\n",ans[i]);
}

B

令 \(v\) 为价值,\(w\) 为代价。注意代价很大而价值很小,所以 \(f(i,v)\) 表示前 \(i\) 个物品得到价值 \(v\) 的最小代价,每个询问二分回答即可。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
#include<ctime>
#include<cstdlib>
using namespace std;
#define int long long
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned long long ull;
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	return x*f;
}
const int N=310,M=310*310,inf=0x3f3f3f3f3f3f3f3fll;
int Ans[100010],f[2][M];
struct node{int t,v,w;}a[N];
bool cmp(node x,node y){return x.t<y.t;}
struct Query{int t,w,pos;}q[100010];
bool cmp1(Query x,Query y){return x.t<y.t;}
int Min[M];
signed main()
{
	freopen("market.in","r",stdin);
	freopen("market.out","w",stdout);
	int n=read(),m=read(),vv=300*300;
	for(int i=1;i<=n;i++)a[i].w=read(),a[i].v=read(),a[i].t=read();
	sort(a+1,a+n+1,cmp);
	
//	puts("SHOPS:");
//	for(int i=1;i<=n;i++)printf("w=%lld, v=%lld, t=%lld\n",a[i].w,a[i].v,a[i].t);
	
	for(int i=1;i<=m;i++)q[i].t=read(),q[i].w=read(),q[i].pos=i;
	
	sort(q+1,q+m+1,cmp1);
	memset(f,0x3f,sizeof(f));
	memset(Min,0x3f,sizeof(Min));
	f[0][0]=0,a[n+1].t=inf;
	for(int i=1,j=1;i<=n;i++)
	{
		for(int j=0;j<=vv;j++)f[i&1][j]=inf;
		for(int j=vv;j>=0;j--)
		{
			f[i&1][j]=f[(i&1)^1][j];
			if(j>=a[i].v)f[i&1][j]=min(f[i&1][j],f[(i&1)^1][j-a[i].v]+a[i].w);
		}
		for(int j=vv;j>=0;j--)Min[j]=min(Min[j+1],f[i&1][j]);
		for(;j<=m&&q[j].t<a[i+1].t;j++)
		{
			if(q[j].t<a[i].t)continue;
			int L=0,R=vv,pos=0;
			while(L<=R)
			{
				int mid=(L+R)>>1;
				if(Min[mid]<=q[j].w)pos=mid,L=mid+1;
				else R=mid-1;
			}
			Ans[q[j].pos]=pos;
		}
	}
	for(int i=1;i<=m;i++)printf("%lld\n",Ans[i]);
}

C

设连通块 \(A\) 的直径为 \(u_0-v_0\),\(B\) 为 \(u_1-v_1\),那两个连通块 \(A,B\) 合并时直径一定是这四个点中的两个组成的路径,那么线段树分治即可,并查集维护一下直径端点。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
#include<ctime>
#include<bitset>
#include<cstdlib>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned long long ull;
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	return x*f;
}
void write(int n)
{
	if(n>9)write(n/10);
	putchar(n%10^48);
}
const int N=70010,M=N<<1;
int head[N],ver[M],nxt[M],tot=0,n,m;
void add(int x,int y)
{
	ver[++tot]=y;
	nxt[tot]=head[x];
	head[x]=tot;
}
bool vis[N];int t,fa[N][30],dep[N];
void bfs(int s)
{
	queue<int> que;
	que.push(s);
	vis[s]=dep[s]=1;
	while(!que.empty())
	{
		int x=que.front();que.pop();
		for(int i=head[x];i;i=nxt[i])
		{
			int y=ver[i];if(vis[y])continue;
			que.push(y),fa[y][0]=x;
			for(int j=1;j<=t;j++)fa[y][j]=fa[fa[y][j-1]][j-1];
			vis[y]=1,dep[y]=dep[x]+1;
		}
	}
}
int lca(int x,int y)
{
	if(dep[x]<dep[y])swap(x,y);
	if(dep[fa[x][16]]>=dep[y])x=fa[x][16];
	if(dep[fa[x][15]]>=dep[y])x=fa[x][15];
	if(dep[fa[x][14]]>=dep[y])x=fa[x][14];
	if(dep[fa[x][13]]>=dep[y])x=fa[x][13];
	if(dep[fa[x][12]]>=dep[y])x=fa[x][12];
	if(dep[fa[x][11]]>=dep[y])x=fa[x][11];
	if(dep[fa[x][10]]>=dep[y])x=fa[x][10];
	if(dep[fa[x][9]]>=dep[y])x=fa[x][9];
	if(dep[fa[x][8]]>=dep[y])x=fa[x][8];
	if(dep[fa[x][7]]>=dep[y])x=fa[x][7];
	if(dep[fa[x][6]]>=dep[y])x=fa[x][6];
	if(dep[fa[x][5]]>=dep[y])x=fa[x][5];
	if(dep[fa[x][4]]>=dep[y])x=fa[x][4];
	if(dep[fa[x][3]]>=dep[y])x=fa[x][3];
	if(dep[fa[x][2]]>=dep[y])x=fa[x][2];
	if(dep[fa[x][1]]>=dep[y])x=fa[x][1];
	if(dep[fa[x][0]]>=dep[y])x=fa[x][0];
	if(x==y)return x;
	if(fa[x][16]!=fa[y][16])x=fa[x][16],y=fa[y][16];
	if(fa[x][15]!=fa[y][15])x=fa[x][15],y=fa[y][15];
	if(fa[x][14]!=fa[y][14])x=fa[x][14],y=fa[y][14];
	if(fa[x][13]!=fa[y][13])x=fa[x][13],y=fa[y][13];
	if(fa[x][12]!=fa[y][12])x=fa[x][12],y=fa[y][12];
	if(fa[x][11]!=fa[y][11])x=fa[x][11],y=fa[y][11];
	if(fa[x][10]!=fa[y][10])x=fa[x][10],y=fa[y][10];
	if(fa[x][9]!=fa[y][9])x=fa[x][9],y=fa[y][9];
	if(fa[x][8]!=fa[y][8])x=fa[x][8],y=fa[y][8];
	if(fa[x][7]!=fa[y][7])x=fa[x][7],y=fa[y][7];
	if(fa[x][6]!=fa[y][6])x=fa[x][6],y=fa[y][6];
	if(fa[x][5]!=fa[y][5])x=fa[x][5],y=fa[y][5];
	if(fa[x][4]!=fa[y][4])x=fa[x][4],y=fa[y][4];
	if(fa[x][3]!=fa[y][3])x=fa[x][3],y=fa[y][3];
	if(fa[x][2]!=fa[y][2])x=fa[x][2],y=fa[y][2];
	if(fa[x][1]!=fa[y][1])x=fa[x][1],y=fa[y][1];
	if(fa[x][0]!=fa[y][0])x=fa[x][0],y=fa[y][0];
	return fa[x][0];
}
int dist(int x,int y){return dep[x]+dep[y]-2*dep[lca(x,y)];}
int u[N],v[N],L[N],R[N],Ans[N];
struct dsu
{
	int fa[N],sz[N],a[N],b[N],top,d[N];
	pii st[N],p[N];
	//st.first:father, st.second:son
	void init(int n){for(int i=1;i<=n;i++)fa[i]=i,sz[i]=1,a[i]=i,b[i]=-1,d[i]=0;}
	int getf(int x){return fa[x]==x?x:getf(fa[x]);}
	dsu(){top=0;}
	void mg(int x,int y)
	{
		int fx=getf(x),fy=getf(y);
		if(sz[fx]>sz[fy])
		{
			st[++top]=mp(fx,fy);
			p[top]=mp(a[fx],b[fx]); 
			fa[fy]=fx;
			sz[fx]+=sz[fy];
			int l=0,r=0,dis=-1;
			if(~a[fx]&&~b[fx]&&dist(a[fx],b[fx])>dis)dis=dist(a[fx],b[fx]),l=a[fx],r=b[fx];
			if(~a[fx]&&~a[fy]&&dist(a[fx],a[fy])>dis)dis=dist(a[fx],a[fy]),l=a[fx],r=a[fy];
			if(~a[fx]&&~b[fy]&&dist(a[fx],b[fy])>dis)dis=dist(a[fx],b[fy]),l=a[fx],r=b[fy];
			if(~b[fx]&&~a[fy]&&dist(b[fx],a[fy])>dis)dis=dist(b[fx],a[fy]),l=b[fx],r=a[fy];
			if(~b[fx]&&~b[fy]&&dist(b[fx],b[fy])>dis)dis=dist(b[fx],b[fy]),l=b[fx],r=b[fy];
			if(~a[fy]&&~b[fy]&&dist(a[fy],b[fy])>dis)dis=dist(a[fy],b[fy]),l=a[fy],r=b[fy];
			d[fx]=dis,a[fx]=l,b[fx]=r;
		}
		else
		{
			st[++top]=mp(fy,fx);
			p[top]=mp(a[fy],b[fy]); 
			fa[fx]=fy;
			sz[fy]+=sz[fx]; 
			int l=0,r=0,dis=-1;
			if(~a[fx]&&~b[fx]&&dist(a[fx],b[fx])>dis)dis=dist(a[fx],b[fx]),l=a[fx],r=b[fx];
			if(~a[fx]&&~a[fy]&&dist(a[fx],a[fy])>dis)dis=dist(a[fx],a[fy]),l=a[fx],r=a[fy];
			if(~a[fx]&&~b[fy]&&dist(a[fx],b[fy])>dis)dis=dist(a[fx],b[fy]),l=a[fx],r=b[fy];
			if(~b[fx]&&~a[fy]&&dist(b[fx],a[fy])>dis)dis=dist(b[fx],a[fy]),l=b[fx],r=a[fy];
			if(~b[fx]&&~b[fy]&&dist(b[fx],b[fy])>dis)dis=dist(b[fx],b[fy]),l=b[fx],r=b[fy];
			if(~a[fy]&&~b[fy]&&dist(a[fy],b[fy])>dis)dis=dist(a[fy],b[fy]),l=a[fy],r=b[fy];
			d[fy]=dis,a[fy]=l,b[fy]=r;
		}
	}
	void back()
	{
		sz[st[top].fi]-=sz[st[top].se];
		fa[st[top].se]=st[top].se;
		a[st[top].fi]=p[top].fi;
		b[st[top].fi]=p[top].se;
		d[st[top].fi]=dist(p[top].fi,p[top].se); 
		top--;
	}
}B;
struct sgt
{
	vector<int>vec[N<<2];
	struct seg
	{int l,r;}t[N<<2];
	void build(int p,int l,int r)
	{
		t[p].l=l,t[p].r=r;
		if(l==r)return;
		int mid=(l+r)/2;
		build(p*2,l,mid);
		build(p*2+1,mid+1,r);
	}
	void modify(int p,int l,int r,int d)
	{
		if(l<=t[p].l&&t[p].r<=r)
		{
			vec[p].pb(d);
			return;
		}
		int mid=(t[p].l+t[p].r)/2;
		if(l<=mid)modify(p*2,l,r,d);
		if(r>mid)modify(p*2+1,l,r,d);
	}
	void dfs(int p,int ans)
	{
		int pre=vec[p].size();
		for(int i=0;i<vec[p].size();i++)
		B.mg(u[vec[p][i]],v[vec[p][i]]),ans=max(ans,B.d[B.getf(u[vec[p][i]])]); 
		if(t[p].l==t[p].r)
		{
			Ans[t[p].l]=ans;
			for(int i=0;i<vec[p].size();i++)B.back();
			return;
		}
		dfs(p*2,ans),dfs(p*2+1,ans);
		for(int i=0;i<vec[p].size();i++)B.back();
	}
}T;
int main()
{
	freopen("ds.in","r",stdin);
	freopen("ds.out","w",stdout);
	n=read(),m=read();
	for(int i=1;i<n;i++){u[i]=read(),v[i]=read(),L[i]=read(),R[i]=read();add(u[i],v[i]),add(v[i],u[i]);}
	t=16,bfs(1);
	B.init(n);
	T.build(1,1,n);
	for(int i=1;i<n;i++)T.modify(1,L[i],R[i],i);
	T.dfs(1,0);
	for(int i=1;i<=m;i++)write(Ans[read()]),putchar('\n');
}

D

\(\mathcal O(n^2)\) 的做法就是枚举连续的乘法段,两边都是加号,算出现次数,就是 \(\sum_{i\le j} 2^{\max\{i-2,0\}}\cdot 2^{\max\{n-j-1,0\}}\cdot\prod_{k=i}^ja_k\)。注意到把 \(j\) 弄出来的话对于每个 \(j\) 的贡献是一个形如一堆 \(\sum \left(2^{x}\prod a_i\right)\) 的形式,这是可以线性推出来的,预处理个 \(2^k\) 就可以 \(\mathcal O(n)\)。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
#include<ctime>
#include<cstdlib>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned long long ull;
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	return x*f;
}
const int mod=1e9+7,N=1e5+10;
int qpow(int a,int n)
{
	int ans=1;
	while(n)
	{
		if(n&1)ans=1ll*a*ans%mod;
		a=1ll*a*a%mod;
		n>>=1;
	}
	return ans;
}
int sum[N],inv[N],a[N];
int main()
{
	freopen("calc.in","r",stdin);
	freopen("calc.out","w",stdout);
	sum[0]=inv[0]=1;
	int n=read();for(int i=1;i<=n;i++)a[i]=read();
	for(int i=1;i<=n;i++)sum[i]=1ll*sum[i-1]*a[i]%mod,inv[i]=qpow(sum[i],mod-2);
	int ans=0;
	int s=0;
	for(int i=1;i<=n;i++)
	{
		s=(1ll*s*a[i]%mod+1ll*a[i]*qpow(2,max(i-2,0))%mod)%mod;
		ans=(ans+1ll*s*qpow(2,max(n-i-1,0))%mod)%mod;
	}
	printf("%d",ans);
}

标签:dep,fx,fy,Day4,多校,fa,int,include,BZOJ
来源: https://www.cnblogs.com/juruo-zzt/p/15335302.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有