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<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,p[N],fa[N],a[N],s[N],t,ans;
bool flag=;
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=;
for (int j=p[x];j;j=edge[j].nxt) son++;
if (son==) a[x]=;
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=;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_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
const char LL[]="%I64d\n";
#endif
n=read();
for (int i=;i<=n;i++)
{
int x=read();fa[i]=x;addedge(x,i);
}
for (int i=;i<=n;i++) s[i]=read();
a[]=s[];dfs();
if (flag)
{
ll ans=;
for (int i=;i<=n;i++) ans+=a[i];
cout<<ans;
}
else cout<<-;
return ;
//NOTICE LONG LONG!!!!!
}

  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<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,m,tot,v=N;
vector<char> a[N],b[N],ans[N];
char c[]={'A','C','G','T'};
bool flag[];
void check()
{
//cout<<b[0][0]<<b[0][1]<<endl<<b[1][0]<<b[1][1]<<endl;
tot=;
for (int i=;i<n;i++)
b[i][]=b[i-][],b[i][]=b[i-][];
for (int j=;j<m;j++)
{
int ans1=,ans2=;
for (int i=;i<n;i++)
ans1+=(a[i][j]!=b[i%][j%]),
ans2+=(a[i][j]!=b[i%^][j&]);
if (ans1<ans2)
{
for (int i=;i<n;i++)
b[i][j]=b[i%][j&];
}
else
{
for (int i=;i<n;i++)
b[i][j]=b[i%^][j&];
}
}
for (int i=;i<n;i++)
for (int j=;j<m;j++)
tot+=a[i][j]!=b[i][j];
if (tot<v)
{
v=tot;
for (int i=;i<n;i++)
for (int j=;j<m;j++)
ans[i][j]=b[i][j];
}
for (int i=;i<m;i++) b[][i]=b[][i&],b[][i]=b[][i&];
for (int i=;i<n;i++)
{
int ans1=,ans2=;
for (int j=;j<m;j++)
ans1+=a[i][j]!=b[i%][j&],ans2+=a[i][j]!=b[i%][j&^];
if (ans1<ans2)
{
for (int j=;j<m;j++) b[i][j]=b[i%][j&];
}
else
{
for (int j=;j<m;j++) b[i][j]=b[i%][j&^];
}
}
tot=;
for (int i=;i<n;i++)
for (int j=;j<m;j++)
tot+=a[i][j]!=b[i][j];
if (tot<v)
{
v=tot;
for (int i=;i<n;i++)
for (int j=;j<m;j++)
ans[i][j]=b[i][j];
}
}
void dfs(int x,int y)
{
if (x>) {check();return;}
for (int i=;i<;i++)
if (!flag[i])
{
b[x][y]=c[i];
flag[i]=;
if (y==) dfs(x+,);
else dfs(x,);
flag[i]=;
}
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
const char LL[]="%I64d\n";
#endif
n=read(),m=read();
for (int i=;i<n;i++)
for (int j=;j<m;j++)
a[i].push_back(getc());
for (int i=;i<n;i++)
for (int j=;j<m;j++)
b[i].push_back(' '),ans[i].push_back(' ');
dfs(,);
for (int i=;i<n;i++)
{
for (int j=;j<m;j++)
putchar(ans[i][j]);
printf("\n");
}
return ;
//NOTICE LONG LONG!!!!!
}

  然后就垫底了。感觉应该早点弃掉这个毒瘤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=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),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]=;a[deep[k]]++;
if (1ll*(k-)*x+>n) return;
for (int i=(k-)*x+;i<=min(n,k*x+);i++)
{
deep[i]=deep[k]+;
dfs(i,n,x);
size[k]+=size[i];
}
}
ll check(int n,int k)
{
deep[]=;memset(a,,sizeof(a));dfs(,n,k);
ll s=;for (int i=;i<=n;i++) s+=size[i];
return s;
}
void build(int d)
{
int s=;
for (int i=;i<=n;i++)
{
for (int j=s+;j<=s+a[i];j++)
fa[j]=s-a[i-]+(j-s-)/d+;
s+=a[i];
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("c.in","r",stdin);
freopen("c.out","w",stdout);
#endif
cin>>n>>m;
int l=,r=n-;
if ((1ll*n*(n+)>>)<m) {cout<<"NO";return ;}
if ((1ll*n*(n+)>>)==m)
{
cout<<"YES\n";
for (int i=;i<n;i++) printf("%d ",i);
return ;
}
while (l<=r)
{
int mid=l+r>>;
if (check(n,mid)<=m) ans=mid,r=mid-;
else l=mid+;
}
if (!ans) {cout<<"NO";return ;}
ll s=check(n,ans);
int cur=n;while (cur&&a[cur]<=) cur--;
int maxdeep;for (maxdeep=;maxdeep<=n;maxdeep++) if (a[maxdeep]==) break;
maxdeep--;
for (;;)
{
if (m==s) break;
while (a[cur]==) cur--;
if (maxdeep+-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=;i<=n;i++) printf("%d ",fa[i]);
return ;
}

Codeforces Round #530 Div. 1 自闭记的更多相关文章

  1. Educational Codeforces Round 58 Div. 2 自闭记

    明明多个几秒就能场上AK了.自闭. A:签到. #include<iostream> #include<cstdio> #include<cmath> #inclu ...

  2. Codeforces Round #554 (Div. 2)自闭记

    A 签到 #include<bits/stdc++.h> using namespace std; ],t[],ans; int main() { scanf("%d%d&quo ...

  3. Codeforces Round #545 Div. 1自闭记

    A:求出该行该列各有多少个比其小的取max,该行该列各有多少个比其大的取max,加起来即可. #include<iostream> #include<cstdio> #incl ...

  4. Codeforces Round #528 Div. 1 自闭记

    整天自闭. A:有各种讨论方式.我按横坐标排了下然后讨论了下纵坐标单调和不单调两种情况.写了15min也就算了,谁能告诉我printf和cout输出不一样是咋回事啊?又调了10min啊?upd:突然想 ...

  5. Codeforces Round #526 Div. 1 自闭记

    日常猝死. A:f[i]表示子树内包含根且可以继续向上延伸的路径的最大价值,统计答案考虑合并两条路径即可. #include<iostream> #include<cstdio> ...

  6. Codeforces Round #567 (Div. 2)自闭记

    嘿嘿嘿,第一篇文章,感觉代码可以缩起来简直不要太爽 打个div2发挥都这么差... 平均一题fail一次,还调不出错,自闭了 又一次跳A开B,又一次B傻逼错误调不出来 罚时上天,E还傻逼了..本来这场 ...

  7. Codeforces Round #525 Div. 2 自闭记

    A:签到. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> ...

  8. Codeforces Round #530 (Div. 2)F Cookies (树形dp+线段树)

    题:https://codeforces.com/contest/1099/problem/F 题意:给定一个树,每个节点有俩个信息x和t,分别表示这个节点上的饼干个数和先手吃掉这个节点上一个饼干的的 ...

  9. Codeforces Round #530 (Div. 2) F (树形dp+线段树)

    F. Cookies 链接:http://codeforces.com/contest/1099/problem/F 题意: 给你一棵树,树上有n个节点,每个节点上有ai块饼干,在这个节点上的每块饼干 ...

随机推荐

  1. MSTECHLNK

    MSTECHLNK(微软技术直通车) 时间:2017.12.16地点:微软中关村办公楼天安门会议室

  2. 如何判断Android设备是否为模拟器

    android.os.Build.BRAND:获取设备品牌 如果获取的Landroid/os/Build;->BRAND的值为 "generic"则为模拟器上运行. andr ...

  3. javaScript之jQuery框架

    一.jQuery简介   jQuery是一个快速.简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(或JavaScript框架).jQuery设计的宗旨 ...

  4. mfc CFileFind查找类

    查找文件 CFileFind类 提取文件图标 显示大图标 显示小图标 一.查找文件 . CFileFind类 //c:\mydir\myfile.txt GetFileName 获取文件名 myfil ...

  5. CS229笔记:分类与逻辑回归

    逻辑回归 对于一个二分类(binary classification)问题,\(y \in \left\{0, 1\right\}\),如果直接用线性回归去预测,结果显然是非常不准确的,所以我们采用一 ...

  6. CSS布局的一些技巧

    max-width 通常使元素水平居中用的较多的方法为: #main { width: 600px; margin: 0 auto; } 但是,当浏览器窗口比元素的宽度还要窄时,浏览器会显示一个水平滚 ...

  7. Elasticsearch Query DSL 整理总结(一)—— Query DSL 概要,MatchAllQuery,全文查询简述

    目录 引言 概要 Query and filter context Match All Query 全文查询 Full text queries 小结 参考文档 引言 虽然之前做过 elasticse ...

  8. JQuery快速入门-事件与效果

    一.事件 事件绑定的方法有两种: 绑定到元素 查找元素后绑定事件 方法1:绑定到元素 <body> <p onclick='func1()'>点击我</p> < ...

  9. python基础篇----基本数据类型

    bit  #bit_length 当前数字的二进制,只用用n位来表示a = 123b = a.bit_length()print(b)#==>7

  10. Git版本库的创建(Ubuntu)

    在Ubuntu上学习Git随笔. 一. git 仓库的安装 git 在终端用git命令查看Ubuntu是否安装git版本库,如果没有安装,最新版本(Ubuntu18.04)会提示用下面命令进行安装. ...