D
给你子序列11,10,01,00的个数,问是否存在这样的01序列,若有则输出一种。
简单数学题
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<set>
#include<math.h>
#include<queue>
#include<map>
#include<stack>
#include<deque>
#define go(i,a,b) for (int (i)=(a);(i)<=(b);(i)++)
#define ll long long
#define MOD 1000000007
#define N 100005
using namespace std;
ll a00,a01,a10,a11;
int main(){
scanf("%lld%lld%lld%lld",&a00,&a01,&a10,&a11);
bool flag=true;
if(a00==0&&a01==0&&a10==0&&a11==0) printf("0");
else{
ll tot0,tot1;
if (a00==0){
if (a01||a10) tot0=1;
else tot0=0;
}
else{
tot0=sqrt(2*a00)+1;
}
if (a11==0){
if (a01||a10) tot1=1;
else tot1=0;
}
else{
tot1=sqrt(2*a11)+1;
}
//cout<<tot0<<" "<<tot1<<endl;
if (tot0*(tot0-1)/2!=a00||tot1*(tot1-1)/2!=a11||tot1*tot0!=a10+a01){
cout<<"Impossible"<<endl;
return 0;
}
ll tot=tot1+tot0;
for (int i=1;i<=tot;i++){
if (a10>=tot0&&tot1>0){
printf("1");
a10-=tot0;
tot1--;
}
else{
printf("0");
tot0--;
}
}
}
return 0;
}
/*
6 0 0 0
0 0 3 3
1 2 2 1
*/
E
树形DP
可以对树进行一种操作,删去一条边再加上一条边。
问对于任意一个点可不可以通过这个操作来使得他成为树的重心。
重心的定义:删去这个点之后的各块大小均不大于n/2
有想法,无法实现,学习了一下multiset的使用方法,之前从来没有用过……
一些函数记录
int main(){
multiset<int> s1,s2;
s1.insert(1);
s2.insert(2);
s1==s2;
int num=s1.count(element);
int *p=s1.find(element);
s1.erase(s1.find(element)); //删除可能有多个的单个元素
s1.erase(element); //删除所有值为element的元素
int minn=c.begin(); //第一个元素
int maxn=c.rbegin(); //最后一个元素(逆向迭代)
}
题目代码
即判断向上和向下切割
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<set>
#include<math.h>
#include<queue>
#include<map>
#include<stack>
#include<deque>
#define go(i,a,b) for (int (i)=(a);(i)<=(b);(i)++)
#define ll long long
#define MOD 1000000007
#define N 400005
using namespace std;
vector<int> e[N];
int n;
int maxd[N],sum[N],hev[N],hevsize[N],maxu[N];
void dfs1(int u, int fa){
sum[u]=1;
for (int i=0;i<e[u].size();i++){
int v=e[u][i];
if (v!=fa){
dfs1(v,u);
sum[u]+=sum[v];
//cout<<" "<<u<<" "<<v<<endl;
if (sum[v]<=n/2) maxd[u]=max(maxd[u],sum[v]);
else maxd[u]=max(maxd[u],maxd[v]);
if (sum[v]>hevsize[u]){
hevsize[u]=sum[v];
hev[u]=v;
}
}
}
return;
}
void dfs2(int u, int fa){
multiset<int> s;
for (int i=0;i<e[u].size();i++){
int v=e[u][i];
if (v!=fa){
if (sum[v]<=n/2) s.insert(sum[v]);
else s.insert(maxd[v]);
}
}
for (int i=0;i<e[u].size();i++){
int v=e[u][i];
if (v!=fa){
if (n-sum[v]<=n/2) maxu[v]=n-sum[v];
else{
maxu[v]=max(maxu[v],maxu[u]);
s.erase(s.find(sum[v]));
if (!s.empty()){
maxu[v]=max(*s.rbegin(),maxu[v]);
}
s.insert(sum[v]);
}
dfs2(v,u);
}
}
return ;
}
int main(){
int u,v;
scanf("%d",&n);
for (int i=1;i<=n-1;i++){
scanf("%d%d",&u,&v);
e[u].push_back(v);
e[v].push_back(u);
}
memset(maxu,0,sizeof(maxu));
memset(maxd,0,sizeof(maxd));
dfs1(1,-1);
dfs2(1,-1);
for (int i=1;i<=n;i++){
bool flag=true;
if (n-sum[i]>n/2&&n-sum[i]-maxu[i]>n/2) flag=false;
if (sum[hev[i]]-maxd[hev[i]]>n/2) flag=false;
if (i==1) cout<<flag;
else cout<<" "<<flag;
}
return 0;
}
/*
6 0 0 0
0 0 3 3
1 2 2 1
*/