• CCO2017题解


    #2750. 「CCO 2017」Vera 与道路建设

    为数不多的可做题之一……

    考虑题目要求要用较少的边构造很多的点对,观察样例,容易想到环。

    一个大小为(n)的环,有(frac12 n(n-1))对点。

    则解法就是构造一堆环,然后用边连起来就好了(题目要求为连通图)。

    时间复杂度(Theta(n+sqrt n))

    #include<bits/stdc++.h>
    using namespace std;
    #define inf 1e9
    const int maxn=2e5+10;
    const int mod=1e9+7;
    int k,n,m=-1,a[maxn],b[maxn],top;
    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-'0';c=getchar();}
    	return x*f;
    }
    inline int divide(int val){
    	int l=1,r=10000,res=1;
    	while(l<=r){
    		int mid=(l+r)>>1;
    		if(a[mid]<=val)res=mid,l=mid+1;
    		else r=mid-1;
    	}
    	return res;
    }
    int main(){
    	for(int i=1;i<=10000;i++)
    		a[i]=i*(i-1)/2;
    	k=read();
    	while(k!=0){
    		b[++top]=divide(k);
    		k-=a[b[top]];
    		n+=b[top],m+=b[top]+1;
    	}
    	printf("%d %d
    ",n,m);
    	int num=1;
    	for(int i=1;i<=top;i++){
    		if(num>1)printf("%d %d
    ",num-1,num);
    		for(int j=num;j<num+b[i]-1;j++)
    			printf("%d %d
    ",j,j+1);
    		printf("%d %d
    ",num+b[i]-1,num);
    		num+=b[i];
    	}
    	return 0;
    }
    

    #2751. 「CCO 2017」矩形帝国的霸业

    正解=暴搜?复杂度=玄学?对,就是这样。

    直接暴搜+一点点记忆化即可,注意有的地方可以稍微贪心一下。

    贪心时注意留足保证正确性的余地。

    欢迎各位大佬踊跃证明复杂度,反正我是不太会。

    #include<bits/stdc++.h>
    inline int min(int x,int y){return x<y?x:y;}
    inline int max(int x,int y){return x>y?x:y;}
    inline void swap(int &x,int &y){int t=x;x=y;y=t;}
    #define inf 1e9
    const int maxn=5e3+10;
    const int mod=1e9+7;
    const int T=5e3+5;
    int n,m,f[maxn][maxn],g[maxn][maxn];
    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-'0';c=getchar();}
    	return x*f;
    }
    inline int mn(int n,int m){
    	if(n<m)swap(n,m);
    	if(m==0)return 0;
    	if(m==1)return (n&1)?inf:n/2;
    	if(n<=T&&f[n][m])return f[n][m];
    	int ans=inf;
    	if(n<4*m){
    		if(n%2==0&&m>=n/2)ans=min(ans,mn(n,m-n/2)+1);
    		if(n>=m*2)ans=min(ans,mn(n-2*m,m)+1);
    		if(m%2==0)ans=min(ans,mn(n-m/2,m)+1);
    	}else ans=min(ans,mn(n%(2*m)+2*m,m)+n/(2*m)-1);
    	if(n<=T)f[n][m]=ans;
    	return ans;
    }
    inline int mx(int n,int m){
    	if(n<m)swap(n,m);
    	if(m==0)return 0;
    	if(m==1)return (n&1)?-inf:n/2;
    	if(n<=T&&g[n][m])return g[n][m];
    	int ans=-inf;
    	if(n>=2*m){
    		if(m%2==0)return mx(n%(m/2)+3*m/2,m)+n/(m/2)-3;
    		return mx(n%(2*m),m)+n/(2*m);
    	}else{
    		if(n%2==0)ans=max(ans,mx(n,m-n/2)+1);
    		if(m%2==0)ans=max(ans,mx(n-m/2,m)+1);
    		if(n<=T)g[n][m]=ans;
    		return ans;
    	}
    }
    int main(){
    	n=read(),m=read();
    	printf("%d %d
    ",mn(n,m),mx(n,m));
    	return 0;
    }
    

    #2752. 「CCO 2017」Vera 与现代艺术

    大常数的(map+01trie),评测机就是用来信仰的。

    对每个(x_i)建一棵(01trie),存放(y_i),不同的是第(i)层存放(2^i)(这样的好处是高位都可以被模掉)。

    对每个(r_i)暴力枚举二的幂次,然后在(01trie)里查询即可。

    真不明白( ext{luogu})为什么给一个没人做的毒瘤卡常题评蓝,太低了吧。

    #include<bits/stdc++.h>
    using namespace std;
    #define inf 1e9
    const int maxn=1e7+3e6+10;
    const int mod=1e9+7;
    typedef long long ll;
    int n,m;
    inline int hb(ll x){
    	for(int i=60;~i;--i)
    		if(x>>i&1)return i;
    }
    map<pair<ll,int>,int>rt;
    int ch[2][maxn],val[maxn],tot;
    
    int main(){
    	scanf("%d%d",&n,&m);ll x,y;
    	for(int i=1,v;i<=n;++i){
    		scanf("%lld%lld%d",&x,&y,&v);
    		int u=rt[{x^(1ll<<hb(x)),hb(x)}];
    		if(!u)rt[{x^(1ll<<hb(x)),hb(x)}]=u=++tot;
    		for(int j=0,k=hb(y);j<k;++j){
    			if(!ch[y>>j&1][u])ch[y>>j&1][u]=++tot;
    			u=ch[y>>j&1][u];
    		}
    		val[u]+=v;
    	}
    	for(int i=1,v;i<=m;++i){
    		scanf("%lld%lld",&x,&y);v=0;
    		for(int j=0,j1=hb(x);j<=j1;++j)
    			if(rt.count({x&((1ll<<j)-1),j}))
    			for(int k=0,k1=hb(y),u=rt[{x&((1ll<<j)-1),j}];u&&k<=k1;++k)
    				v+=val[u],u=ch[y>>k&1][u];
    		printf("%d
    ",v);
    	}
    	return 0;
    }
    

    #2753. 「CCO 2017」接雨滴

    考虑将高度从大到小排序。

    (f[i][j])表示用了前(i)块地,柱子和水的体积和为(j)合不合法。

    ( ext{bitset})暴力转移即可。

    具体内容细品代码。

    #include <bits/stdc++.h>
    using namespace std;
    const int N=505;
    const int M=30005;
    bitset<M>f[N],ans;
    int n,a[N],sum;
    int main(){
        cin>>n;
        for(int i=1;i<=n;i++)cin>>a[i];
        for(int i=1;i<=n;i++)sum+=a[i];
        sort(a+1,a+n+1,greater<int>());
        f[1][a[1]]=1;
        for(int i=2;i<=n;i++){
            for(int j=i;j<=n;j++)
    	      f[j]|=f[j-1]<<a[i];
            ans|=f[n];
        }
        for(int i=sum;i<M;i++)
    	if(ans[i])printf("%d ",i-sum);
        return 0;
    }
    

    #2754. 「CCO 2017」专业网络

    这题挺难的,( ext{luogu})只评绿,实在搞不懂。

    按代价排序,贪心地选取。

    若第(i)个人想免费,那么( ext{Ta})一定是第([a_i+1,n])个被结识的。

    如果这个区间已经占满了,则付费,否则选取最左侧的空位。

    正确性显然,线段树维护即可。

    #include<bits/stdc++.h>
    using namespace std;
    #define inf 1e9
    const int maxn=2e5+10;
    const int mod=1e9+7;
    int n,tr[maxn<<2],ans;
    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-'0';c=getchar();}
    	return x*f;
    }
    struct node{int a,b;}p[maxn];
    inline int cmp(node x,node y){return x.b>y.b;}
    inline int update(int h,int l,int r,int x,int y){
    	if(tr[h]==r-l+1)return 0;
    	if(l>y||r<x)return 0;
    	//if(l==r)printf(" %d",l);
    	if(l==r)return tr[h]=1;
    	if(l>=x&&r<=y){
    		int mid=(l+r)>>1;
    		if(tr[h<<1]<mid-l+1)update(h<<1,l,mid,x,y);
    		else update(h<<1|1,mid+1,r,x,y);
    		tr[h]=tr[h<<1]+tr[h<<1|1];
    		return 1;
    	}
    	int mid=(l+r)>>1;
    	int flag=update(h<<1,l,mid,x,y);
    	if(!flag)flag|=update(h<<1|1,mid+1,r,x,y);
    	tr[h]+=flag;
    	return flag;
    }
    inline int query(int h,int l,int r,int x,int y){
    	if(l>y||r<x)return 0;
    	if(l>=x&&r<=y)return tr[h];
    	int mid=(l+r)>>1;
    	return query(h<<1,l,mid,x,y)+query(h<<1|1,mid+1,r,x,y);
    }
    int main(){
    	n=read();
    	for(int i=1;i<=n;i++)
    		p[i].a=read(),p[i].b=read();
    	sort(p+1,p+1+n,cmp);
    	for(int i=1;i<=n;i++){
    		//printf("%d:",p[i].b);
    		ans+=(1-update(1,1,n,p[i].a+1,n))*p[i].b;
    		//puts("
    ");
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

    #2755. 「CCO 2017」移动数组

    全网无题解,至今不会做。

  • 相关阅读:
    Spring Cloud微服务实战 打造企业级优惠券系统 7-2 优惠券模块实体类相关列值枚举定义
    Spring Cloud微服务实战 打造企业级优惠券系统 7-1 创建优惠券模块微服务
    阿里云 oss (一) 工具上传图片
    Gateway 过滤器,过滤器统一异常处理
    GatewayFilterFactory 不生
    docker 安装 redis
    json 时区问题
    小程序checkbox
    小程序拍照功能
    Learning sensorimotor control with neuromorphic sensors: Toward hyperdimensional active perception
  • 原文地址:https://www.cnblogs.com/syzf2222/p/14389148.html
Copyright © 2020-2023  润新知