• 2018-2019 XIX Open Cup, Grand Prix of Korea 解题报告


    H

    我们枚举化简后有多少对(x'=frac{x}{gcd(i,j)})(y'=frac{y}{gcd(i,j)}),然后就可以得出有多少(gcd(i,j))满足条件。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define ll long long
    ll input(){
    	ll x=0,f=0;char ch=getchar();
    	while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
    	while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    	return f? -x:x;
    }
    
    ll A,B,C,D;
    
    int main(){
    	A=input(),B=input(),C=input(),D=input();
    
    	ll Ans=0;
    
    	for(int i=1;i<1000;i++){
    		for(int j=1;j+i<1000;j++){
    			if(__gcd(i,j)!=1) continue;
    			// cout<<(D/j)<<" "<<(B/i)<<" "<<(A-1)/i<<" "<<(C-1)/j<<endl;
    			ll tmp=min((D/j),(B/i))-max((A-1)/i,(C-1)/j);
    			// if(tmp>0)cout<<tmp<<endl;
    			if(tmp<=0) continue;
    			Ans+=tmp;
    		}
    	}
    	printf("%lld
    ",Ans);
    }
    

    F

    签到题,递归构造,重复利用即可。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define ll long long
    ll input(){
    	ll x=0,f=0;char ch=getchar();
    	while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
    	while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    	return f? -x:x;
    }
    
    const int N=2e5+7;
    ll id,ls[N],rs[N];
    map <ll,int> mp;
    
    void init(){mp.clear();id=-1;}
    
    void dfs(ll n){
    	if(mp.find(n)!=mp.end()) return;
    	if(n==1){
    		mp[n]=++id,ls[id]=-1,rs[id]=-1;
    		return;
    	}
    	dfs(n-n/2),dfs(n/2);
    	mp[n]=++id,ls[id]=mp[n-n/2],rs[id]=mp[n/2];
    }
    
    int main(){
    	int T=input();
    	while(T--){
    		init();
    		ll n=input();
    		dfs(n);
    		printf("%lld
    ",id+1);
    		for(int i=0;i<=id;i++){
    			printf("%lld %lld
    ",ls[i],rs[i]);
    		}
    		printf("%lld
    ",id);
    	}
    }
    

    L

    预处理出,每个点向右不递减最远到达的距离和严格递减到达的距离。对于每个询问暴力的处理块数和坏数的个数,然后记忆化答案。复杂度是调和级数的复杂度O(nlogn)。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define ll long long
    ll input(){
    	ll x=0,f=0;char ch=getchar();
    	while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
    	while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    	return f? -x:x;
    }
    
    const int N=1e5+7;
    
    int n,m;
    int a[N],mx[N],mi[N];
    int Ans[N],block[N];
    
    int main(){
    	n=input();
    
    	for(int i=1;i<=n;i++) a[i]=input(),Ans[i]=-1,block[i]=0;
    
    	for(int i=1;i<=n;){
    		int len=0,id=i;
    		for(int j=i+1;j<=n;j++){
    			if(a[j]>=a[j-1]) len++,id=j;
    			else break;
    		}
    
    		for(int j=i;j<=id;j++) mx[j]=id;
    		i=id+1;
    	}
        for(int i=1;i<=n;){
            int len=0,id=i;
            for(int j=i+1;j<=n;++j){
                if(a[j]<a[j-1]) len++,id=j;
                else break;
            }
            for(int j=i;j<=id;++j)mi[j]=id;
            i=id+1;
        }
    
        int Q=input();
    
        for(int i=1;i<=Q;i++){
        	int mr=input();
        	if(Ans[mr]!=-1){
        		printf("%d %d
    ",block[mr],Ans[mr]);
        	}else{
        		int cnt=0,bad=0;
        		for(int i=1;i<=n;){
        			int tmp=max(mx[i],mi[i]);
        			int to=min(i+mr-1,n);
        			// cout<<i<<":tmp="<<tmp<<" to="<<to<<endl;
        			if(tmp>=to){
        				cnt++;
        				i=tmp+1;
        			}else{
        				cnt++;
        				bad+=(to-tmp);
        				i=to+1;
        			}
        			// cout<<"bad="<<bad<<" cnt="<<cnt<<endl;
        		}
        		printf("%d %d
    ",block[mr]=cnt,Ans[mr]=bad);
        	}
        }
    
    }
    

    I

    sg函数,一直不太擅长这套理论,在这里学到了许多。在这里每加一条线相当于增加了两个后继局面,(j)(i-j-2),然后就是传统的sg函数推导了。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define ll long long
    ll input(){
    	ll x=0,f=0;char ch=getchar();
    	while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
    	while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    	return f? -x:x;
    }
    
    const int N=5007;
    
    int f[N],S[N],sg[N];
    
    void init(){
    	memset(sg,0,sizeof sg);
    
    	sg[1]=0,sg[2]=1;
    
    	for(int i=3;i<N;i++){
    		memset(S,0,sizeof(S));
    		for(int j=0;j<=i-2;j++)
    			S[sg[i-j-2]^sg[j]]=1;
    		for(int j=0;;j++)
    			if(!S[j]){sg[i]=j;break;}
    	}
    }
    
    int main(){
    	init();
    
    	int T=input();
    	while(T--){
    		int n=input();
    		if(sg[n]) printf("First
    ");
    		else printf("Second
    ");
    	}
    }
    

    E

    阅读理解题,英语、语文都不太好,死活读不懂题意。

    题意:n个点,m条边,要求判断是否仅存在串联和并联并且有从源点到汇点使得图是一个简单电路

    题解:对于一条链可以压缩为直接一条边到达,不断压缩后判断是否只有源点和汇点即可。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define ll long long
    ll input(){
    	ll x=0,f=0;char ch=getchar();
    	while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
    	while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    	return f? -x:x;
    }
    
    const int N=1e5+7;
    
    int n,m,cnt;
    int vis[N];
    set <int> G[N];
    
    void del(int x){
    	if(G[x].size()==2){
    		vis[x]=1,cnt--;
    		int u=*G[x].begin();
    		int v=*G[x].rbegin();
    		G[u].erase(x),G[v].erase(x);
    		G[u].insert(v),G[v].insert(u);
    		if(!vis[u]) del(u);
    		if(!vis[v]) del(v);
    	}
    }
    
    int main(){
    	int n=input(),m=input();
    	for(int i=1;i<=m;i++){
    		int u=input(),v=input();
    		G[u].insert(v),G[v].insert(u);
    	}
    
    	cnt=n;
    	for(int i=1;i<=n;i++){
    		if(!vis[i]) del(i);
    	}
    
    	if(cnt==2) printf("Yes
    ");
    	else printf("No
    ");
    }
    
  • 相关阅读:
    7 -- Spring的基本用法 -- 11... 基于XML Schema的简化配置方式
    7 -- Spring的基本用法 -- 10... 获取其他Bean的属性值;获取Field值;获取任意方法的返回值
    Java 代码块:静态代码块、构造代码块、构造函数块
    MyBatis Like
    7 -- Spring的基本用法 -- 9...容器中Bean的生命周期
    my-small.ini、my-medium.ini、my-large.ini、my-huge.ini文件的作用
    java.lang.Class<T> -- 反射机制及动态代理
    7 -- Spring的基本用法 -- 8... 抽象Bean与子Bean;Bean继承与Java继承的区别;容器中的工厂Bean;获得Bean本身的id;强制初始化Bean
    Eclipse Maven 配置setting.xml 的镜像远程仓库
    7 -- Spring的基本用法 -- 7... 创建Bean的3种方式
  • 原文地址:https://www.cnblogs.com/-aether/p/13282004.html
Copyright © 2020-2023  润新知