• AtCoder Beginner Contest 220


    传送门


    A、B、C、D、F比较简单,没必要写出来


    E - Distance on Large Perfect Binary Tree

    题目

    问一个深度为 (n)的满二叉树有多少个点对的距离恰好为 (D)
    (nleq 10^6,Dleq 2*10^6)


    分析

    其实此题也比较简单但是赛时没调出来QAQ

    考虑分成两种情况讨论,一种情况是其中一个为 (LCA)

    那么这个就是(sum_{i=1}^n2^{i-1}*2^D[i+Dleq n])

    另一种就枚举其中一个点往下的度数,也就是

    [frac{1}{2}sum_{i=1}^n2^{i-1}sum_{x=1}^{D-1}2^x*2^{D-x}[i+D-xleq n][i+xleq n] ]

    也就是

    [frac{1}{2}sum_{i=1}^n2^{i-1}sum_{x=max(1,i+D-n)}^{min(n-i,D-1)}2^D ]


    代码

    #include <cstdio>
    #define rr register
    using namespace std;
    const int mod=998244353;
    int two[2000011],ans,n,m;
    inline signed max(int a,int b){return a>b?a:b;}
    inline signed min(int a,int b){return a<b?a:b;}
    signed main(){
    	scanf("%d%d",&n,&m),two[0]=1;
    	for (rr int i=1;i<=n*2;++i) two[i]=2ll*two[i-1]%mod;
    	for (rr int i=1;i<=n;++i){
    		rr int l=max(1,i+m-n),r=min(m-1,n-i);
    		if (l<=r) ans=(ans+1ll*(r-l+1)*two[i-1]%mod*two[m-1]%mod)%mod;	
    	}
    	for (rr int i=m+1;i<=n;++i) ans=(ans+two[i])%mod;
    	return !printf("%d",ans);
    }
    

    G - Isosceles Trapezium

    题目

    给定 (n) 个点,点权为 (w_i)

    问其中四个点构成的等腰梯形的最大点权和


    分析

    等腰梯形的上底和下底中点的连线垂直于上底和下底,用这个性质枚举线段即可


    代码

    #include <cstdio>
    #include <cctype>
    #include <map>
    #include <algorithm>
    #define rr register
    using namespace std;
    const int N=1011; typedef long long lll;
    map<pair<double,double>,int>uk; lll ans=-4e9;
    map<pair<lll,lll>,lll>K[N*N]; int n,lA,lB,cnt;
    map<pair<lll,lll>,lll>::iterator it;
    struct Point{lll x,y,w;}a[N],A[N*N],B[N*N];
    inline signed iut(){
    	rr int ans=0,f=1; rr char c=getchar();
    	while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans*f;
    }
    inline lll max(lll a,lll b){return a>b?a:b;}
    bool cmpx(Point x,Point y){return x.x<y.x||(x.x==y.x&&x.y<y.y);}
    bool cmpy(Point x,Point y){return x.y<y.y||(x.y==y.y&&x.x<y.x);}
    signed main(){
    	n=iut();
    	for (rr int i=1;i<=n;++i)
    		a[i]=(Point){iut(),iut(),iut()};
    	for (rr int i=1;i<n;++i)
    	for (rr int j=i+1;j<=n;++j){
    		rr Point t=(Point){a[i].x+a[j].x,a[i].y+a[j].y,a[i].w+a[j].w};
    		if (a[i].x==a[j].x) A[++lA]=t;
    		else if (a[i].y==a[j].y) B[++lB]=t;
    		else {
    		    rr double k=(double)(a[j].x-a[i].x)/(a[i].y-a[j].y),b=t.y-k*t.x;
    		    if (!uk[make_pair(k,b)]) uk[make_pair(k,b)]=++cnt;
    		    rr int pos=uk[make_pair(k,b)];
    		    rr lll now=K[pos][make_pair(t.x,t.y)];
    			K[pos][make_pair(t.x,t.y)]=max(now,t.w);
    		}
    	}
    	for (rr int i=1;i<=cnt;++i){
    		rr lll now=-2e9;
    		for (it=K[i].begin();it!=K[i].end();++it){
    			if (now!=-2e9) ans=max(ans,now+(it->second));
    			now=max(now,it->second);
    		}
    	}
    	sort(A+1,A+1+lA,cmpy),sort(B+1,B+1+lB,cmpx);
    	for (rr int l=1,r;l<=lA;l=r+1){
    		for (r=l;A[l].y==A[r].y;++r); --r;
    		rr int j=l; rr lll now=-2e9;
    		for (rr int i=l+1;i<=r;++i){
    			for (;A[j].x<A[i].x;++j) now=max(now,A[j].w);
    			if (now!=-2e9) ans=max(ans,now+A[i].w);
    		}
    	}
    	for (rr int l=1,r;l<=lB;l=r+1){
    		for (r=l;B[l].x==B[r].x;++r); --r;
    		rr int j=l; rr lll now=-2e9;
    		for (rr int i=l+1;i<=r;++i){
    			for (;B[j].y<B[i].y;++j) now=max(now,B[j].w);
    			if (now!=-2e9) ans=max(ans,now+B[i].w);
    		}
    	}
    	if (ans==-4e9) printf("-1");
    	    else printf("%lld",ans);
    	return 0;
    }
    

    H - Security Camera

    题目

    给出一张 (n) 个点,(m) 条边的无向图,问有多少个点集相邻的边数量为偶数
    (nleq 40)


    分析

    这个相邻的边不好搞,不过点集的补集要满足其导出子图的边数与 (m) 奇偶性相同。
    理应用meet in the middle写的,但是其实可用状态很少,直接dp在2s内还是可以跑过的
    (dp[i][x][y]) 表示前 (i) 个点之间连边奇偶性为 (x=0/1)
    且第 (i) 个点之后的连边奇偶性状态为 (y) 的点集数量


    代码

    int main(){
    	n=iut(),m=iut();
    	for (rr int i=1;i<=m;++i){
    		rr int x=iut(),y=iut();
    		a[x]|=1ll<<(y-x-1);//扔掉小于x的状态
    	}
    	dp[0][m&1][0]=1;
    	for (rr int i=0;i<n;++i)
    	for (rr int j=0;j<2;++j)
    	for (it=dp[i][j].begin();it!=dp[i][j].end();++it){
    		rr lll fi=it->first,se=it->second;
    		dp[i+1][(j^fi)&1][(fi>>1)^a[i+1]]+=se;//选择这个点就要判断与该点连边的边数是否为奇数
    		dp[i+1][j][fi>>1]+=se;
    	}
    	return !printf("%lld",dp[n][0][0]);
    }
    
  • 相关阅读:
    GO语言的进阶之路-Golang字符串处理以及文件操作
    将本地的代码推送到公网的github账号去
    GO语言的进阶之路-go的程序结构以及包简介
    Linux操作系统原理
    Linux安装-kickstart无人值守安装
    LVM逻辑卷管理
    Liunx软Raid实现
    parted分区工具用法
    高级Linux运维工程师必备技能(扫盲篇)
    H3C配置FTP服务器
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/15344670.html
Copyright © 2020-2023  润新知