• Codeforces Round #530 (Div. 1)


    A - Sum in the tree

    就是贪心选尽量让上面的点权尽量大,那么对于偶数层的点,其到根节点的和即为所有儿子中的最大值。

    #include<bits/stdc++.h>
    using namespace std;
    
    char gc() {
    //	static char buf[100000],*p1,*p2;
    //	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin))?EOF:*p1++;
    	return getchar();
    }
    
    template<class T>
    int read(T &ans) {
    	T f=1;ans=0;
    	char ch=gc();
    	while(!isdigit(ch)) {
    		if(ch==EOF) return EOF;
    		if(ch=='-') f=-1;
    		ch=gc();
    	}
    	while(isdigit(ch))
    		ans=ans*10+ch-'0',ch=gc();
    	ans*=f;return 1;
    }
    
    template<class T1,class T2>
    int read(T1 &a,T2 &b) {
    	return read(a)==EOF?EOF:read(b);
    }
    
    template<class T1,class T2,class T3>
    int read(T1 &a,T2 &b,T3 &c) {
    	return read(a,b)==EOF?EOF:read(c);
    }
    
    typedef long long ll;
    const int Maxn=1100000;
    const int inf=0x3f3f3f3f;
    const ll mod=1000000007;
    
    int s[Maxn],to[Maxn],nxt[Maxn],first[Maxn],tot=1;
    int n,x,flag;
    ll ans;
    
    inline void add(int u,int v) {
    	to[tot]=v;
    	nxt[tot]=first[u];
    	first[u]=tot++;
    }
    
    void dfs(int root) {
    	if(s[root]==-1) {
    		int temp=inf;
    		for(int i=first[root];i;i=nxt[i]) {
    			dfs(to[i]);
    			temp=min(temp,s[to[i]]);
    		}
    		s[root]=temp;
    		for(int i=first[root];i;i=nxt[i]) {
    			ans+=s[to[i]]-s[root];
    		}
    	}
    	else {
    		for(int i=first[root];i;i=nxt[i]) {
    			dfs(to[i]);
    			if(s[to[i]]==inf) s[to[i]]=s[root];
    			if(s[to[i]]<s[root]) flag=1;
    			ans+=s[to[i]]-s[root];
    		}
    	}
    }
    
    int main() {
    	read(n);
    	for(int i=2;i<=n;i++) {
    		read(x);
    		add(x,i);
    	}
    	for(int i=1;i<=n;i++) read(s[i]);
    	dfs(1);ans+=s[1];
    	if(flag) return 0*puts("-1");
    	printf("%I64d",ans);
    	return 0;
    }
    

    B - Nice table

    这个结论就是要么是对于每一行都只有两种字符或每一列都只有两种字符。至于为什么。。自己感性理解一下就好了。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cctype>
    #include<string>
    #include<iostream>
    #define qmin(x,y) (x=min(x,y))
    #define qmax(x,y) (x=max(x,y))
    using namespace std;
    
    inline char gc() {
    //	static char buf[100000],*p1,*p2;
    //	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    	return getchar();
    }
    
    template<class T>
    int read(T &ans) {
    	ans=0;char ch=gc();T f=1;
    	while(!isdigit(ch)) {
    		if(ch==EOF) return -1;
    		if(ch=='-') f=-1;
    		ch=gc();
    	}
    	while(isdigit(ch))
    		ans=ans*10+ch-'0',ch=gc();
    	ans*=f;return 1;
    }
    
    template<class T1,class T2>
    int read(T1 &a,T2 &b) {
    	return read(a)!=EOF&&read(b)!=EOF?2:EOF;
    }
    
    template<class T1,class T2,class T3>
    int read(T1 &a,T2 &b,T3 &c) {
    	return read(a,b)!=EOF&&read(c)!=EOF?3:EOF;
    }
    
    typedef long long ll;
    const int Maxn=310000;
    const int inf=0x3f3f3f3f;
    
    char t[4]={'A','T','C','G'};
    string a[Maxn],b[Maxn];
    int w[Maxn][4][4],w1[Maxn][4][4];
    int p[4],p1[4],p2[4],n,m;
    
    inline bool check() {
    	return p[1]!=1||p[2]!=2||p[3]!=3||p[0]!=0;
    }
    
    int calc() {
    	int ans=0;
    	for(int i=0,t=2;i<m;i++,t^=2)
    		ans+=min(w[i][p[0+t]][p[1+t]],w[i][p[1+t]][p[0+t]]);
    	return ans;
    }
    
    signed main() {
    //	freopen("test.in","r",stdin);
    	read(n,m);
    	for(int i=0;i<n;i++) cin>>a[i];
    	for(int i=0;i<m;i++)
    		for(int x=0;x<4;x++)
    			for(int y=0;y<4;y++)
    				for(int j=0;j<n;j++)
    					if(j&1) w[i][x][y]+=(t[y]!=a[j][i]);
    					else w[i][x][y]+=(t[x]!=a[j][i]);
    	int ans1=inf,ans2=inf;
    	for(int i=0;i<4;i++) p[i]=i;
    	do {
    		int temp=calc();
    		if(temp<ans1) {
    			ans1=temp;
    			memcpy(p1,p,sizeof(p));
    		}
    	}
    	while(next_permutation(p,p+4),check());
    	for(int i=0;i<m;i++) b[i].resize(n);
    	for(int i=0;i<n;i++)
    		for(int j=0;j<m;j++) b[j][i]=a[i][j];
    	memcpy(w1,w,sizeof(w1));
    	memset(w,0,sizeof(w));
    	swap(n,m);
    	for(int i=0;i<m;i++)
    		for(int x=0;x<4;x++)
    			for(int y=0;y<4;y++)
    				for(int j=0;j<n;j++)
    					if(j&1) w[i][x][y]+=(t[y]!=b[j][i]);
    					else w[i][x][y]+=(t[x]!=b[j][i]);
    	do {
    		int temp=calc();
    		if(temp<ans2) {
    			ans2=temp;
    			memcpy(p2,p,sizeof(p));
    		}
    	}
    	while(next_permutation(p,p+4),check());
    	swap(n,m);
    	if(ans1<ans2)
    		for(int i=0;i<n;i++,puts(""))
    			for(int j=0;j<m;j++)
    				if(j&1) putchar(t[p1[(w1[j][p1[0]][p1[1]]>w1[j][p1[1]][p1[0]])^(i&1)]]);
    				else putchar(t[p1[(w1[j][p1[2]][p1[3]]>w1[j][p1[3]][p1[2]])^(i&1)+2]]);
    	else
    		for(int i=0;i<n;i++,puts(""))
    			for(int j=0;j<m;j++)
    				if(i&1) putchar(t[p2[(w[i][p2[0]][p2[1]]>w[i][p2[1]][p2[0]])^(j&1)]]);
    				else putchar(t[p2[(w[i][p2[2]][p2[3]]>w[i][p2[3]][p2[2]])^(j&1)+2]]);
    	return 0;
    }
    

    C - Construct a tree

    首先就是分叉数越大,其对应的所有子树的大小和越小。那么依次枚举判断,如果合法构造即可。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cctype>
    #define qmin(x,y) (x=min(x,y))
    #define qmax(x,y) (x=max(x,y))
    using namespace std;
    
    inline char gc() {
    //	static char buf[100000],*p1,*p2;
    //	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    	return getchar();
    }
    
    template<class T>
    int read(T &ans) {
    	ans=0;char ch=gc();T f=1;
    	while(!isdigit(ch)) {
    		if(ch==EOF) return -1;
    		if(ch=='-') f=-1;
    		ch=gc();
    	}
    	while(isdigit(ch))
    		ans=ans*10+ch-'0',ch=gc();
    	ans*=f;return 1;
    }
    
    template<class T1,class T2>
    int read(T1 &a,T2 &b) {
    	return read(a)!=EOF&&read(b)!=EOF?2:EOF;
    }
    
    template<class T1,class T2,class T3>
    int read(T1 &a,T2 &b,T3 &c) {
    	return read(a,b)!=EOF&&read(c)!=EOF?3:EOF;
    }
    
    typedef long long ll;
    const int Maxn=110000;
    const int inf=0x3f3f3f3f;
    
    int n,a[Maxn],p[Maxn];
    ll s;
    
    ll check(int x) {
    	ll res=n,temp=1,ans=0;
    	for(int i=1;res;i++) {
    		qmin(temp,res);
    		ans+=temp*i;
    		res-=temp;
    		temp*=x;
    	}
    	return ans;
    }
    
    void work(int x) {
    	a[1]=1;s--;
    	ll res=n-1,temp=x,t=2;
    	for(;res;t++) {
    		qmin(temp,res);
    		s-=temp*t;
    		a[t]=temp;
    		res-=temp;
    		temp*=x;
    	}
    	for(int i=t-1;s;i--) {
    		while(a[i]>1) {
    			a[i]--;
    			s+=i;
    			if(s>t) {
    				s-=t;
    				a[t++]++;
    			}
    			else {
    				a[s]++;
    				s=0;
    				break;
    			}
    		}
    	}
    	int sum=0,tempp=1;
    	for(int i=1;i<t;i++) {
    		int temp=sum+1;
    		sum=tempp;
    		for(int j=temp;j<=sum;j++)
    			for(int k=min(a[i+1],x);k;k--) {
    				p[++tempp]=j;
    				a[i+1]--;
    			}
    	}
    	for(int i=2;i<=n;i++) printf("%d ",p[i]);
    }
    
    signed main() {
    //	freopen("test.in","r",stdin);
    	read(n,s);
    	if(1ll*n*(n+1)/2==s) {
    		puts("Yes");
    		for(int i=2;i<=n;i++) printf("%d ",i-1);
    		return 0;
    	}
    	if(1ll*n*(n+1)/2<s||2*n-1>s) {
    		puts("No");
    		return 0;
    	}
    	for(int i=2;i<=n;i++) if(check(i)<=s) {
    		puts("Yes");
    		work(i);
    		return 0;
    	}
    	return 0;
    }
    
  • 相关阅读:
    Java中关系操作符==的学习以及与equals的对比
    关于alibaba.fastjson的使用
    给有C或C++基础的Python入门 :Python Crash Course 1
    快速幂基本模板
    断言封装及应用(有难度)
    断言封装之key检查及kv实战示例
    正则取值及断言实战示例
    关联实现下-jsonpath取值(有难度!!耗时长)
    关联实现上-jsonpath取值
    requests顺序执行实现
  • 原文地址:https://www.cnblogs.com/shanxieng/p/10228982.html
Copyright © 2020-2023  润新知