zoukankan      html  css  js  c++  java
  • 杭二集训 2019.8.17

    T1

    题目意思:给出l,r,p,求区间[l,r]之间有多少数的最小质因子是p。

    数据范围:1<=l<=r<=1000000000,1<=p<=1000000000

    Solution:

    考虑设(f(x,y))表示从1到(x)中最小质因子为(y)的数的个数,则有

    [f(x,y)=lfloor {xover y} floor -sum_{k=2,kin pri}^{min(lfloor {xover y} floor,y-1)} f(lfloor {xover y} floor,k) ]

    其中(pri)为质数集合,特别的,当(y otin pri)时,此函数返回0

    Code:

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=1e7+1;
    int L,R,P;
    int isprime(int x){
    	for(int i=2;i*i<=x;i++)
    		if(x%i==0) return 0;
    	return 1;
    }
    int calc(int x,int p){
    	if(!isprime(p)) return 0;
    	int v=x/p,re=0;
    	for(int i=2;i<=min(p-1,v);i++)
    		re+=calc(v,i);
    	return v-re;
    }
    int read(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    	while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    	return x*f;
    }
    signed main(){
        L=read(),R=read(),P=read();
    	printf("%lld
    ",calc(R,P)-calc(L-1,P));
    	return 0;
    }
    
    

    T2

    题目意思:定义一个可重正整数集合是好的,当且仅当该集合中任意两个数之和不为质数。给你一个序列,希望你从中取出一个尽量大的好的集合。

    数据范围:N<=3000,1<=hi<=100000

    Solution:

    我们知道,除了2以外的质数都是奇数,而只有奇数+偶数=奇数

    则我们考虑将集合分为奇数和偶数,将和为质数的两个数连边,然后网络流最小割

    在此之前特判一下2的情况就行了

    Code:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=3003;
    const int M=2e5+1;
    const int inf=1947483647;
    int ans,n,cnt=1,head[N],a[N],cur[N];
    int S,T,pos,tot,vis[M],pri[M];
    struct Edge{int nxt,to,v;}edge[N*N];
    void prepare(){
    	for(int i=2;i<=M;i++){
    		if(!vis[i]) pri[++tot]=i;
    		for(int j=1;j<=tot&&pri[j]*i<=M;j++){
    			vis[i*pri[j]]=1;
    			if(i%pri[j]==0) break;
    		}
    	}
    }
    void ins(int x,int y,int z){
    	edge[++cnt].nxt=head[x];
    	edge[cnt].to=y;head[x]=cnt;
    	edge[cnt].v=z;
    }
    int read(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    	while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    	return x*f;
    }
    namespace NetworkFlow{
    	queue<int> q;
    	int dep[N];
    	int bfs(){
    		memset(dep,0,sizeof(dep));
    		q.push(S);dep[S]=1;
    		while(!q.empty()){
    			int x=q.front();q.pop();
    			if(x==T){while(q.size()) q.pop(); return 1;}
    			for(int i=head[x];i;i=edge[i].nxt)
    				if(!dep[edge[i].to]&&edge[i].v){
    					dep[edge[i].to]=dep[x]+1;
    					q.push(edge[i].to);
    				}
    		}return dep[T];
    	}
    	int dfs(int x,int rest){
    		if(x==T||rest<=0) return rest;
    		int flow=0;
    		for(int& i=cur[x];i;i=edge[i].nxt){
    			int y=edge[i].to,v=edge[i].v;
    			if(v&&dep[y]==dep[x]+1){
    				int now=dfs(y,min(rest,v));
    				edge[i].v-=now;
    				edge[i^1].v+=now;
    				flow+=now;rest-=now;
    				if(rest<=0) break;
    			}
    		}return flow;
    	}
    	int dinic(){
    		int maxflow=0;
    		while(bfs()){
    			for(int i=1;i<=n;i++)
    				cur[i]=head[i];
    			maxflow+=dfs(S,inf);
    		}
    		return maxflow;
    	}
    }
    int main(){
    	n=read();prepare();
    	for(int i=1;i<=n;i++){
    		a[i]=read();
    		if(pos&&a[i]==1){
    			i--,n--;
    			continue;
    		}if(a[i]==1) pos=i;
    	}S=n+1,T=S+1;
    	for(int i=1;i<=n;i++){
    		if(!(a[i]&1)) ins(S,i,1),ins(i,S,0);
    		else ins(i,T,1),ins(T,i,0);
    		for(int j=i+1;j<=n;j++)
    			if(!vis[a[i]+a[j]]){
    				if(!(a[i]&1)) ins(i,j,1),ins(j,i,0);
    				else ins(j,i,1),ins(i,j,0);
    			}
    	}
    	int maxmatch=NetworkFlow::dinic();
    	printf("%d
    ",n-maxmatch);
    	return 0;
    }
    
    

    T3

    题目意思:给定一个长度为n的数列ai,求一个最长的ai的子序列bi,满足对于任意i,(b_i)=(b_{i-1})

    Solution:

    QAQ

    Code:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+1;
    int n,ans=1,a[N];
    int read(){
    	int x=0,f=1;char ch=getchar();;
    	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    	while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    	return x*f;
    }
    int main(){
    	n=read();
    	for(int i=1;i<=n;i++) a[i]=read();
    	sort(a+1,a+n+1);int re=1;
    	for(int i=2;i<=n;i++){
    		if(a[i]==a[i-1]) ++re;
    		else ans=max(ans,re),re=1;
    	}printf("%d
    ",max(ans,re));
    	return 0;
    }
    
    
  • 相关阅读:
    ReentrantLock(重入锁)的源码解析
    vue项目使用vue-photo-preview插件实现点击图片放大预览和移动
    BOM简单总结
    js中属性类型:数据属性与访问器属性
    Javascript面向对象编程(三):非构造函数的继承(对象的深拷贝与浅拷贝)
    Javascript面向对象编程(二):构造函数的继承 作者:yuan一峰
    Javascript 面向对象编程(一):封装 作者:yuan一峰
    js面向对象、创建对象的工厂模式、构造函数模式、原型链模式
    Vue中父子组件执行的先后顺序
    Vue子组件调用父组件的方法
  • 原文地址:https://www.cnblogs.com/NLDQY/p/11396568.html
Copyright © 2011-2022 走看看