zoukankan      html  css  js  c++  java
  • [CLYZ2017]day11

    约数

    image

    Solution

    20分

    暴力求值.

    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<stack>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define M 700000
    #define N 10000005
    using namespace std;
    typedef long long ll;
    ll d[N],ans;
    int f[N],p[M],a[M],t[M],n,m,cnt;
    inline void prime(){
         for(int i=2;i<=n;++i){
            if(!f[i]){
    			p[++cnt]=f[i]=i;
            }
            for(int j=1;j<=cnt&&i*p[j]<=n;++j){
                f[i*p[j]]=p[j];
                if(!(i%p[j])) break;
            }        
        }
    }
    inline void func_d(int k){
    	d[k]=1;
    	int x=k,y,cnt;
    	while(x>1){
    		cnt=0;y=f[x];
    		while(!(x%y))
    			x/=y,++cnt;
    		d[k]*=(cnt+1ll);
    	}
    }
    inline void dfs(int u,int x,int k){
    	if(u>m){
    		ans+=d[x];return;
    	}
    	dfs(u+1,x,k);
    	for(int i=1;i<=t[u];++i){
    		x*=a[u];dfs(u+1,x,k);
    	}
    } 
    inline void func_ans(int k){
    	m=0;
    	int x=k;
    	while(x>1){
    		a[++m]=f[x];t[m]=0;
    		while(!(x%a[m]))
    			x/=a[m],++t[m];
    	}
    	dfs(1,1,k); 
    }
    inline void Aireen(){
    	scanf("%d",&n);
    	prime();
    	for(int i=1;i<=n;++i) func_d(i);
    	for(int i=1;i<=n;++i) func_ans(i);
    	printf("%lld\n",ans);
    }
    int main(){
    	freopen("divisor.in","r",stdin);
    	freopen("divisor.out","w",stdout);
    	Aireen();
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

    100分

    把式子展开为\(\sum_{i=1}^n\sum_{p|i}\sum_{q|p}1\).
    \(q\times\lfloor\frac{p}{q}\rfloor\times\lfloor\frac{i}{p}\rfloor\leq{n}\),即求满足\(xyz\leq{n}(x,y,z\in{N^{+}})\)的三元组个数.
    假设\(x\leq{y}\leq{z}\),枚举加上组合,容斥求即可.

    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<stack>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    ll n;
    inline ll ans1(){
    	ll ret=0;
    	for(ll i=1;i*i*i<=n;++i)
    		for(ll j=i;i*j*j<=n;++j)
    			ret+=n/(i*j)-j+1;
    	return ret; 
    }
    inline ll ans2(){
    	ll ret=0;
    	for(ll i=1;i*i<=n;++i)
    		ret+=n/(i*i);
    	return ret; 
    }
    inline ll ans3(){
    	ll ret=0;
    	for(ll i=1;i*i*i<=n;++i)
    		++ret;
    	return ret;
    }
    inline void Aireen(){
    	scanf("%lld",&n);
    	printf("%lld\n",ans1()*6ll-ans2()*3ll-ans3()*2ll);
    }
    int main(){
    	freopen("divisor.in","r",stdin);
    	freopen("divisor.out","w",stdout);
    	Aireen();
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

    最小生成树

    image

    Solution

    100分

    如果选择了第\(i\)次操作的边,必然也选择了\((A_i,B_i)=C\)这条边.
    那么\(A,B\)同属一个集合.
    所以\((A_i,B_i)=C_i,(B_i,A_i+1)=C_i+1\)可以看做\((A_i,A_i+1)=C_i+1\).
    同理,每次加边操作可以看为\((A_i,B_i)=C_i,(A_i,A_i+j)=C_i+2j-1,(B_i,B_i+j)=C_i+2j\).
    后两种每次加边\(O(n)\).
    所以设\(d[i]\)表示\((i,i+1)\)之间的最短路径长度.
    \(d[i]=min\{d[i],d[i-1]+2\}\).
    所以只需初始化\(d[A_i]=C_i+1,d[B_i]=C_i+2\).
    所有操作结束后,循环两圈求\(d[i]\)最小值.

    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<stack>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define N 200005
    #define INF 2000000000
    #define min(a,b) a<b?a:b
    using namespace std;
    typedef long long ll;
    struct edge{
    	int l,r,w;
    }e[N<<1];
    ll ans;
    int fa[N],dis[N],n,m,q;
    inline int read(){
    	int ret=0;char c=getchar();
    	while(!isdigit(c))
    		c=getchar();
    	while(isdigit(c)){
    		ret=(ret<<1)+(ret<<3)+c-'0';
    		c=getchar();
    	}
    	return ret;
    }
    inline bool cmp(edge x,edge y){
    	return x.w<y.w;
    }
    inline int gf(int k){
    	if(fa[k]==k) return k;
    	return fa[k]=gf(fa[k]);
    }
    inline void Aireen(){
    	n=read();q=read();
    	for(int i=1;i<=n;++i) dis[i]=INF;
    	int a,b,c;
    	while(q--){
    		a=read()+1;b=read()+1;c=read();
    		dis[a]=min(dis[a],c+1);
    		dis[b]=min(dis[b],c+2);
    		e[++m]=(edge){a,b,c};
    	}
    	for(int i=2;i<=n;++i)
    		dis[i]=min(dis[i],dis[i-1]+2);
    	dis[1]=min(dis[1],dis[n]+2);
    	for(int i=2;i<=n;++i)
    		dis[i]=min(dis[i],dis[i-1]+2);
    	dis[1]=min(dis[1],dis[n]+2);
    	for(int i=1;i<n;++i)
    		e[++m]=(edge){i,i+1,dis[i]};
    	e[++m]=(edge){n,1,dis[n]};
    	sort(e+1,e+1+m,cmp);
    	for(int i=1;i<=n;++i) fa[i]=i;
    	for(int i=1,j,k;i<=m;++i){
    		j=gf(e[i].l);k=gf(e[i].r);
    		if(j!=k){
    			ans+=e[i].w;fa[j]=k; 
    		}
    	}
    	printf("%lld\n",ans);
    }
    int main(){
    	freopen("spanning.in","r",stdin);
    	freopen("spanning.out","w",stdout);
    	Aireen();
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
    
  • 相关阅读:
    经典的Java基础面试题集锦
    2016春招Android开发实习生(网易传媒)笔试
    十三、集合点和事务
    十一、LoadRunner组成和工作原理
    Java+selenium之WebDriver常见特殊情况如iframe/弹窗处理(四)
    修改jar包内容并打包上传到私服
    Information:java: Multiple encodings set for module chunk platf "GBK" will be used by compile
    十、创建、运行和监控测试场景
    在gitlab新建分支,IDEA切换时找不到的解决办法
    Git 代码撤销、回滚到任意版本(当误提代码到本地或master分支时)
  • 原文地址:https://www.cnblogs.com/AireenYe/p/15612536.html
Copyright © 2011-2022 走看看