A:显然应该让未确定的大小尽量大。不知道写了啥就wa了一发。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 200010
#define inf 1000000010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
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^48),c=getchar();return x*f;
}
int n,p[N],fa[N],a[N],s[N],t,ans;
bool flag=1;
struct data{int to,nxt;
}edge[N];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
void dfs(int k)
{if (!flag) return;for (int i=p[k];i;i=edge[i].nxt){int x=edge[i].to,son=0;for (int j=p[x];j;j=edge[j].nxt) son++;if (son==0) a[x]=0;else{int y=inf;for (int j=p[x];j;j=edge[j].nxt)y=min(y,s[edge[j].to]);if (y<s[k]) {flag=0;break;}a[x]=y-s[k];s[x]=s[k]+a[x];for (int j=p[x];j;j=edge[j].nxt)a[edge[j].to]=s[edge[j].to]-s[x],dfs(edge[j].to);}}
}
signed main()
{
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);const char LL[]="%I64d\n";
#endifn=read();for (int i=2;i<=n;i++){int x=read();fa[i]=x;addedge(x,i);}for (int i=1;i<=n;i++) s[i]=read();a[1]=s[1];dfs(1);if (flag){ll ans=0;for (int i=1;i<=n;i++) ans+=a[i];cout<<ans;}else cout<<-1;return 0;//NOTICE LONG LONG!!!!!
}

View Code

  B:快1.5h时才想到一个不太靠谱的做法,然后交一发就wa on 4了。拍了好一会才发现做法假掉了,内心崩溃。花40min换了一个做法,写的时候就感觉这怎么这么简单肯定是假的,然后就wa on 7了,根本都不用拍就发现做法假掉了,内心崩溃。最后终于发现最开始的做法是能抢救一下的,把第二种做法合并上去就行了,然后就没时间了。

  考虑枚举左上角的2*2方格怎么填。然后考虑前两列,如果将左上角直接向下复制,后面的每一列都只有不相关的两种填法,即两字母交替出现,取最优值即可;如果对左上角复制后进行一些同行内的交换,那么显然会有同一列的连续三行出现不同的字母,这样就固定了每一行都只能是将该行前两个字母复制。

  事实上更优美的想法是最终填法要么每行内两字母交替出现,要么每列内两字母交替出现。根本想不到啊。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define N 300010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
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^48),c=getchar();return x*f;
}
int n,m,tot,v=N;
vector<char> a[N],b[N],ans[N];
char c[4]={'A','C','G','T'};
bool flag[4];
void check()
{//cout<<b[0][0]<<b[0][1]<<endl<<b[1][0]<<b[1][1]<<endl;tot=0;for (int i=2;i<n;i++)b[i][0]=b[i-2][0],b[i][1]=b[i-2][1];for (int j=2;j<m;j++){int ans1=0,ans2=0;for (int i=0;i<n;i++)ans1+=(a[i][j]!=b[i%2][j%2]),ans2+=(a[i][j]!=b[i%2^1][j&1]);if (ans1<ans2){for (int i=0;i<n;i++)b[i][j]=b[i%2][j&1];}else{for (int i=0;i<n;i++)b[i][j]=b[i%2^1][j&1];}}for (int i=0;i<n;i++)for (int j=0;j<m;j++)tot+=a[i][j]!=b[i][j];if (tot<v) {v=tot;for (int i=0;i<n;i++)for (int j=0;j<m;j++)ans[i][j]=b[i][j];}for (int i=2;i<m;i++) b[0][i]=b[0][i&1],b[1][i]=b[1][i&1];for (int i=2;i<n;i++){int ans1=0,ans2=0;for (int j=0;j<m;j++)ans1+=a[i][j]!=b[i%2][j&1],ans2+=a[i][j]!=b[i%2][j&1^1];if (ans1<ans2){for (int j=0;j<m;j++)  b[i][j]=b[i%2][j&1];}else{for (int j=0;j<m;j++) b[i][j]=b[i%2][j&1^1];}}tot=0;for (int i=0;i<n;i++)for (int j=0;j<m;j++)tot+=a[i][j]!=b[i][j];if (tot<v) {v=tot;for (int i=0;i<n;i++)for (int j=0;j<m;j++)ans[i][j]=b[i][j];}
}
void dfs(int x,int y)
{if (x>1) {check();return;}for (int i=0;i<4;i++)if (!flag[i]){b[x][y]=c[i];flag[i]=1;if (y==1) dfs(x+1,0);else dfs(x,1);flag[i]=0;}
}
signed main()
{
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);const char LL[]="%I64d\n";
#endifn=read(),m=read();for (int i=0;i<n;i++)for (int j=0;j<m;j++)a[i].push_back(getc());for (int i=0;i<n;i++)for (int j=0;j<m;j++)b[i].push_back(' '),ans[i].push_back(' ');dfs(0,0);for (int i=0;i<n;i++){for (int j=0;j<m;j++)putchar(ans[i][j]);printf("\n");}return 0;//NOTICE LONG LONG!!!!!
}

View Code

  然后就垫底了。感觉应该早点弃掉这个毒瘤B去看C。哎还是菜爆。

  大号终于变小号了。result:rank 341 rating -39

  C:显然所有点的子树大小之和=所有点的深度之和,那么设度数限制为d,只要找到一组xi满足∑ixi=s且xi>=dxi+1即可。显然度数限制d越大,能构造出s的下界就越小,且增加的这部分边界应该是一段连续区间(因为只要度数限制不为1,就可以找到深度最大且不止一个点的一层,将其中一个点往下拉,使得总深度+1)。于是先找到最小的度数限制,这个随便都能求。然后考虑构造xi,先构造出这个s的下界,再逐渐将其增大。只需要暴力模拟上述证明的过程即可。当然,不能一次只增大1,而是应该直接拉到最底端,以保证复杂度。(虽然事实上只有度数限制<=2时每次增大1的复杂度会出现问题)感觉还是做的太麻烦了。

#include<bits/stdc++.h>
using namespace std;
#define P 1000000007
#define N 100010
#define ll long long
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^48),c=getchar();return x*f;
}
int n,ans,fa[N],a[N],size[N],deep[N];ll m;
void dfs(int k,int n,int x)
{size[k]=1;a[deep[k]]++;if (1ll*(k-1)*x+2>n) return;for (int i=(k-1)*x+2;i<=min(n,k*x+1);i++){deep[i]=deep[k]+1;dfs(i,n,x);size[k]+=size[i];}
}
ll check(int n,int k)
{deep[1]=1;memset(a,0,sizeof(a));dfs(1,n,k);ll s=0;for (int i=1;i<=n;i++) s+=size[i];return s;
}
void build(int d)
{int s=1;for (int i=2;i<=n;i++){for (int j=s+1;j<=s+a[i];j++)fa[j]=s-a[i-1]+(j-s-1)/d+1;s+=a[i];}
}
int main()
{
#ifndef ONLINE_JUDGEfreopen("c.in","r",stdin);freopen("c.out","w",stdout);
#endifcin>>n>>m;int l=1,r=n-1;if ((1ll*n*(n+1)>>1)<m) {cout<<"NO";return 0;}if ((1ll*n*(n+1)>>1)==m){cout<<"YES\n"; for (int i=1;i<n;i++) printf("%d ",i);return 0;}while (l<=r){int mid=l+r>>1;if (check(n,mid)<=m) ans=mid,r=mid-1;else l=mid+1;}if (!ans) {cout<<"NO";return 0;}ll s=check(n,ans);int cur=n;while (cur&&a[cur]<=1) cur--;int maxdeep;for (maxdeep=1;maxdeep<=n;maxdeep++) if (a[maxdeep]==0) break;maxdeep--;for (;;){if (m==s) break;while (a[cur]==1) cur--;if (maxdeep+1-cur>=m-s) a[cur]--,a[cur+m-s]++,m=s;else a[++maxdeep]++,a[cur]--,s+=maxdeep-cur;}build(ans);cout<<"YES\n";for (int i=2;i<=n;i++) printf("%d ",fa[i]);return 0;
}

View Code

转载于:https://www.cnblogs.com/Gloid/p/10227097.html

Codeforces Round #530 Div. 1 自闭记相关推荐

  1. Codeforces Round #530 (Div. 1) C. Construct a tree 想法

    题目链接:http://codeforces.com/contest/1098/problem/C 题意: 给你n个点要你组成一棵以结点1为根的树,使得所有结点的子树的大小和为s,且在这种情况下使得分 ...

  2. Codeforces Round #530 (Div. 1) 1098A Sum in the tree

    A. Sum in the tree Mitya has a rooted tree with nn vertices indexed from 11 to nn, where the root ha ...

  3. Codeforces Round #530 (Div. 2)

    RANK :2252 题数 :3 补题: D - Sum in the tree 思路:贪心 把权值放在祖先节点上 ,预处理 每个节点保存 他与他儿子中 权值最小值即可. 最后会有一些叶子节点依旧为 ...

  4. 【Codeforces Round #767 (Div. 2)】 C. Meximum Array 题解

    [Codeforces Round #767 (Div. 2) ]C. Meximum Array 题解 1629C: Meximum Array 题解 [Codeforces Round #767 ...

  5. Codeforces Round #739 (Div. 3) ABCDEF1F2 解题思路

    Codeforces Round #739 (Div. 3) 可能是一开始大佬都写F1去了,我在D写完后发现F过的人数比E多了好多(个位数与十位数),以为F1比较简单,就直接开F1了,但自己分类讨论老 ...

  6. CodeCraft-19 and Codeforces Round #537 (Div. 2) Editorial

    CodeCraft-19 and Codeforces Round #537 (Div. 2) Editorial A 不说了 代码 #include<bits/stdc++.h> usi ...

  7. Codeforces Round #507 (Div. 1) D. You Are Given a Tree 根号分治 + dp

    传送门 题意: 有一颗nnn个节点的树,其中一个简单路径集合被称为kkk合法当且仅当: 树的每个节点至多属于一条路径,且每条路径恰好包含kkk个点. 对于k∈[1,n]k\in [1,n]k∈[1,n ...

  8. Codeforces Round #585 (Div. 2) E. Marbles 状压dp + 逆序对

    传送门 文章目录 题意: 思路: 题意: 思路: 考虑数列最终的状态一定是相同颜色在一起,所以我们发现他的颜色是有顺序的!显然可以用状压dpdpdp来枚举颜色的顺序,但是又有问题了,你怎么确定当前这个 ...

  9. Codeforces Round #245 (Div. 1) E. Points and Segments 欧拉回路 + 建模

    传送门 文章目录 题意: 思路: 题意: 思路: 考虑对于线段,如何建模. 我们考虑先将线段转换成左闭右开的形式,将左右点连起来. 再考虑每个点,将所有离散化后的点拿出来,每个点都有一个度,现在问题就 ...

最新文章

  1. 服务器收到消息怎么推送给app_「刹那问答24」浅谈FCM推送
  2. no qualifying bean of type_就是要让你彻底学会 @Bean 注解
  3. 设置默认settings文件_Django 学习笔记系列 之 settings.py 设定
  4. 三体智能革命_《三体》之人类的科技文明发展历史其实很诡异
  5. live meeting中白板无法正常使用
  6. linux下source命令使用详解
  7. php 换行 PHP_EOL变量
  8. linux rac 查询ip,你知道RAC怎么增加管理IP地址吗?
  9. mfc formview中的关闭视图函数_VC|API消息处理(回调函数+分支语句)与MFC中的消息映射函数...
  10. memcached高速缓存学习笔记003---利用JAVA程序操作memcached crud操作
  11. SQL server 2008 r2 安装教程
  12. 学习笔记-行政区划匹配缺失补全
  13. java编码规范试题_java编码规范考试题答案完整版.doc
  14. HTML+CSS 模仿淘宝部分网页(未实现事件)
  15. 计算机类毕业设计评阅书评语,本科毕业论文专家评阅评语
  16. 信通方恒资产评估快讯 -《中国矿业》矿业综述 - 2021年国内外油气资源形势分析及展望
  17. SpringMVC细节(下)
  18. IC验证工具:Ubuntu下Questasim10.7安装(64bit)全攻略
  19. 为什么手机信号满格,但网速却还是那么慢?这4点原因是关键
  20. 3款大数据bi工具,让企业数据分析更简单

热门文章

  1. 不用第三方插件如何统计自己wordpress的访问量
  2. 【51单片机快速入门指南】7:片上EEPROM
  3. Java 异常处理机制
  4. Exynos4412 裸机开发 —— IIC总线
  5. Linux 驱动开发之内核模块开发(四)—— 符号表的导出
  6. Linux下查看文件和文件夹大小的df和du命令
  7. VIM 文件编码识别与乱码处理
  8. CPaintDC、CClientDC、CWindowDC和CMetaFileDC类的主要特点及区别-Windows绘图基础知识
  9. [react] 在react中怎样改变组件状态,以及状态改变的过程是什么?
  10. 前端学习(3279):循环 遍历 2