传送门

为啥这场题目少一点啊……

\(A\)

易知增加的数前面肯定比后面大,那么我们倒着做,然后维护一下最小要加多少就可以了

  1. typedef long long ll;
  2. const int N=1e5+5;
  3. int a[N],b[N],n;ll sum;
  4. int main(){
  5. scanf("%d",&n);
  6. fp(i,1,n)scanf("%d%d",&a[i],&b[i]);
  7. fd(i,n,1)sum=(a[i]+sum+b[i]-1)/b[i]*b[i]-a[i];
  8. printf("%lld\n",sum);
  9. return 0;
  10. }

\(B\)

把\(a_i\)当做\(i\)的父亲,那么问题可以转化为对于\(u\),使每一个儿子的深度分别增加\(1,2,3,...\),最终使深度最深的点深度最小。那么我们对于每一个\(u\)把它的所有儿子按深度从大到小排序之后分别加上\(1,2,3...\)即可

  1. //quming
  2. #include<bits/stdc++.h>
  3. #define R register
  4. #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
  5. #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
  6. #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
  7. template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
  8. template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
  9. using namespace std;
  10. const int N=1e5+5;
  11. struct eg{int v,nx;}e[N<<1];int head[N],tot;
  12. inline void add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
  13. int d[N],st[N],top,n;
  14. inline bool cmp(const int &x,const int &y){return d[x]>d[y];}
  15. void dfs(int u){
  16. d[u]=0;
  17. go(u)dfs(v);
  18. top=0;go(u)st[++top]=v;
  19. sort(st+1,st+1+top,cmp);
  20. fp(i,1,top)cmax(d[u],d[st[i]]+i);
  21. }
  22. int main(){
  23. scanf("%d",&n);
  24. for(R int fa,i=2;i<=n;++i)scanf("%d",&fa),add(fa,i);
  25. dfs(1);
  26. printf("%d\n",d[1]);
  27. return 0;
  28. }

\(C\)

先考虑暴力的\(dp\),设当前在位置\(k\),已经算出了\(f_{k,i}\)表示当前位置\(k\)选则放在\(A\)中,且上一个放在\(B\)中的位置为\(i\)的方案数,\(g_{k,i}\)表示当前位置\(k\)选则放在\(B\)中,且上一个放在\(A\)中的位置为\(i\)的方案数

如果\(a_{k+1}-a_k\geq A\),那么\(f_{k,i}\)可以转移到\(f_{k+1,i}\)。如果\(a_{k+1}-a_i\geq B\),那么\(f_{k,i}\)可以转移到\(g_{k+1,k}\)

\(g\)的转移同理

那么仔细考虑,发现每一次转移只会让某一个前缀清零,或者更新\(f_{k+1,k}\)和\(g_{k+1,k}\),那么我们对于\(f,g\)分别记下第一个不为\(0\)的位置,以及对于每一个\(k\)记下它放在\(A/B\)中时前一个数最大的位置是多少,那么一次转移就可以看做是前缀清零和区间查询,树状数组维护即可

  1. //quming
  2. #include<bits/stdc++.h>
  3. #define R register
  4. #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
  5. #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
  6. #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
  7. template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
  8. template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
  9. using namespace std;
  10. const int P=1e9+7;
  11. inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
  12. inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
  13. inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
  14. inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
  15. int ksm(R int x,R int y){
  16. R int res=1;
  17. for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
  18. return res;
  19. }
  20. typedef long long ll;
  21. const int N=1e5+5;
  22. int n,ma,mb,la[N],lb[N];ll A,B,a[N];
  23. struct bit{
  24. int c[N];
  25. inline void chg(R int x,R int y){for(++x;x<=n+1;x+=x&-x)upd(c[x],y);}
  26. inline int qwq(R int x){R int res=0;for(++x;x;x-=x&-x)upd(res,c[x]);return res;}
  27. inline int query(R int l,R int r){return l>r?0:dec(qwq(r),qwq(l-1));}
  28. }f,g;
  29. int main(){
  30. scanf("%d%lld%lld",&n,&A,&B);
  31. fp(i,1,n)scanf("%lld",&a[i]);
  32. for(R int i=1,ia=0,ib=0;i<=n;++i){
  33. while(ia<n&&a[ia+1]<=a[i]-A)++ia;
  34. while(ib<n&&a[ib+1]<=a[i]-B)++ib;
  35. la[i]=ia,lb[i]=ib;
  36. }
  37. ma=mb=0,f.chg(0,1),g.chg(0,1);
  38. fp(i,2,n){
  39. R int df=g.query(mb,la[i]),dg=f.query(ma,lb[i]);
  40. f.chg(i-1,df),g.chg(i-1,dg);
  41. if(a[i]-a[i-1]<A)ma=i-1;
  42. if(a[i]-a[i-1]<B)mb=i-1;
  43. }
  44. printf("%d\n",add(f.query(ma,n),g.query(mb,n)));
  45. return 0;
  46. }

\(D\)

挺巧妙的,想不到啊~~

首先如果我们采用点分的话,很容易发现上界是\(O(\log n)\)级别的,不过这样并不一定最优

我们考虑给每个点编号,如果同时有两个点\(u,v\)的编号为\(k\),那么它们的路径上至少要有一个点的编号大于\(k\)

那么就分成两种情况讨论,如果\(u\)的两个不同子树中同时有\(k\),则\(u\)的编号必须大于\(k\)

如果\(u\)的某个子树中有\(k\)且那个\(k\)到\(u\)的路径上没有其它大于\(k\)的点,则\(u\)不能取\(k\)

那么直接树形\(dp\)即可,具体细节看代码

  1. //quming
  2. #include<bits/stdc++.h>
  3. #define R register
  4. #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
  5. #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
  6. #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
  7. template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
  8. template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
  9. using namespace std;
  10. const int N=1e5+5;
  11. struct eg{int v,nx;}e[N<<1];int head[N],tot;
  12. inline void add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
  13. int f[N],n,res;
  14. void dfs(int u,int fa){
  15. R int s=0;
  16. go(u)if(v!=fa)dfs(v,u),s|=(f[u]&f[v]),f[u]|=f[v];
  17. if(!f[u])return f[u]=1,void();
  18. R int c=0;
  19. while((1<<c)<=s||(f[u]>>c&1))++c;
  20. f[u]=((f[u]>>c|1)<<c),cmax(res,c);
  21. }
  22. int main(){
  23. scanf("%d",&n);
  24. for(R int i=1,u,v;i<n;++i)scanf("%d%d",&u,&v),add(u,v),add(v,u);
  25. dfs(1,0);
  26. printf("%d\n",res);
  27. return 0;
  28. }

\(E\)

这题是真的神仙啊……

首先我们把它转化为一棵\(k\)叉树,其中每个点有\(k\)个叶子,总共有\(n+m\)个叶节点,其中有\(n\)个黑色(权值为\(1\))和\(m\)个白色(权值为\(0\)),每一个节点的权值为它所有儿子的平均值,那么根节点的权值就是最终的答案

我们发现,如果一个黑色节点\(i\)的深度为\(d_i\),那么根节点最终的答案就是\(x_1=\sum k^{-d_i}\)

那么我们再设所有白色节点的权值为\(1\),然后把这一部分的贡献记为\(x_0\),那么就有一个很显然的结论是\(x_0+x_1=1\)。那么一个方案合法,当且仅当\(x_0\)和\(x_1\)都合法且\(x_0+x_1=1\)

这个条件的充分性显然,而必要性的话,我们就要证明如果\(x_0+x_1=1\)必定有合法解。首先如果\(\sum k^{-d_i}=1\),那么深度最深的点的个数必定是\(k\)的倍数(否则它们的和不可能是整数),我们把这些点合并为深度\(-1\)的点,一直合并下去直到最后只剩一个点,说明这样肯定合法

我们把\(x_1\)转化为一个\(k\)进制小数\((0.a_1a_2a_3a_4....a_l)\),其中\(a_l\neq 0\),那么要保证\(x_1\)和\(1-x_1\)都合法。先来考虑\(x_1\),如果进位的话,可以看做是在这\(l\)个位置上加上总共\(n\)个\(1\)。然而加上进位的话似乎就比较辣手了,考虑到一次进位会使\(k\)个\(1\)变为\(1\)个\(1\),相当于总数减去\(k-1\),那么如果\(x_1\)合法则有\(\sum a_i\equiv n\pmod{k-1}\),反之如果这两个同余,我们一定可以构造出\(x_1\),所以这就是充要条件

然后还得保证\(1-x_1\)合法,我们可以把\(1\)给\(k\)进制分解成一个\(b_1=k-1,b_2=k-1,b_3=k-1,...,b_l=k\)的数,那么\(x_0\)的第\(i\)位\(c_i\)就可以看做\(k-1-a_i\),除了第\(l\)位。因为我们强制\(x_1\)的第\(l\)位不为\(0\),所以\(x_0\)的第\(l\)位也不为\(0\),那么我们强制\(c_l\)先放一个数,然后再\(--m\),那么\(c_l\)也等于\(k-1-a_i\)了,这样这个条件和\(x_1\)的就差不多了

综上所述,一个\(x_1\)合法当且仅当满足以下条件

\[\begin{aligned}
& \sum_{i=1}^l a_i\leq n\\
& \sum_{i=1}^l a_i\equiv n\pmod{k-1}\\
& \sum_{i=1}^l (k-1)-a_i\leq m\\
& \sum_{i=1}^l (k-1)-a_i\equiv m\pmod{k-1}\\
\end{aligned}
\]

设\(f[i][j]\)表示\(x_1\)有\(i\)位,且所有位置的和为\(j\)的方案数,这个可以直接\(O(n^2)dp\)算出,如果对应的\(x_1\)合法就加入答案

  1. //quming
  2. #include<bits/stdc++.h>
  3. #define R register
  4. #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
  5. #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
  6. #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
  7. template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
  8. template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
  9. using namespace std;
  10. const int P=1e9+7;
  11. inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
  12. inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
  13. inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
  14. inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
  15. int ksm(R int x,R int y){
  16. R int res=1;
  17. for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
  18. return res;
  19. }
  20. const int N=2005;
  21. int f[2][N],s[N],n,m,k,t,l,res;
  22. inline int min(R int x,R int y){return x<y?x:y;}
  23. int main(){
  24. scanf("%d%d%d",&n,&m,&k),l=(n+m-1)/(k-1),--m;
  25. f[0][0]=1,t=0;
  26. for(R int i=1;i<=l;++i,t^=1){
  27. s[0]=f[t][0];
  28. fp(j,1,n)s[j]=add(s[j-1],f[t][j]);
  29. fp(j,0,min(n,k-1))f[t^1][j]=s[j];
  30. fp(j,k,n)f[t^1][j]=dec(s[j],s[j-k]);
  31. fp(j,1,n)if(j%(k-1)==n%(k-1)&&i*(k-1)-j<=m&&(i*(k-1)-j)%(k-1)==m%(k-1))
  32. upd(res,dec(f[t^1][j],f[t][j]));
  33. }
  34. printf("%d\n",res);
  35. return 0;
  36. }

AtCoder Grand Contest 009 题解的更多相关文章

  1. AtCoder Grand Contest 009

    AtCoder Grand Contest 009 A - Multiple Array 翻译 见洛谷 题解 从后往前考虑. #include<iostream> #include< ...

  2. AtCoder Grand Contest 009 D:Uninity

    题目传送门:https://agc009.contest.atcoder.jp/tasks/agc009_d 题目翻译 定义只有一个点的树权值为\(0\),若干棵(可以是\(0\)棵)权值为\(k\) ...

  3. AtCoder Grand Contest 009 E:Eternal Average

    题目传送门:https://agc009.contest.atcoder.jp/tasks/agc009_e 题目翻译 纸上写了\(N\)个\(1\)和\(M\)个\(0\),你每次可以选择\(k\) ...

  4. AtCoder Grand Contest 017 题解

    A - Biscuits 题目: 给出 \(n\) 个物品,每个物品有一个权值. 问有多少种选取方式使得物品权值之和 \(\bmod\space 2\) 为 \(p\). \(n \leq 50\) ...

  5. Atcoder Grand Contest 054 题解

    那天晚上由于毕业晚会与同学吃饭喝酒没打 AGC,第二天稍微补了下题,目前补到了 E,显然 AGC 的 F 对于我来说都是不可做题就没补了(bushi A 简单题,不难发现如果我们通过三次及以上的操作将 ...

  6. AtCoder Grand Contest 030题解

    第一次套刷AtCoder 体验良好 传送门 Poisonous Cookies cout<<b+min(c,a+b+); Tree Burning 难度跨度有点大啊 可以证明当第一次转向之 ...

  7. AtCoder Grand Contest 031题解

    题面 传送门 题解 比赛的之后做完\(AB\)就开始发呆了--简直菜的一笔啊-- \(A - Colorful\ Subsequence\) 如果第\(i\)个字母选,那么它前面任意一个别的字母的选择 ...

  8. AtCoder Grand Contest 039 题解

    传送门 \(A\) 首先只有一串的情况下,遇到相同的肯定是改后面那一个最优,然后两串的话可能要分奇偶讨论一下 //quming #include<bits/stdc++.h> #defin ...

  9. AtCoder Grand Contest 017题解

    传送门 \(A\) 直接转移就是了 typedef long long ll; const int N=55; ll f[N][2];int a[N],n,p; int main(){ scanf(& ...

随机推荐

  1. C# HtmlAgilityPack+Selenium爬取需要拉动滚动条的页面内容

    现在大多数网站都是随着滚动条的滑动加载页面内容的,因此单纯获得静态页面的Html是无法获得全部的页面内容的.使用Selenium就可以模拟浏览器拉动滑动条来加载所有页面内容. 前情提要 C#HtmlA ...

  2. Linux下Java变量

    一.JAVA_HOME.PATH.CLASSPATH详解 1.1.JAVA_HOME 指向jdk安装目录,该目录下有bin.lib目录.Eclipse/NetBeans/Tomcat等软件就是通过搜索 ...

  3. js点击按钮复制内容到粘贴板

    复制内容到粘贴板,就是要选择需要复制的内容并执行document.execCommand("copy")命令: //复制内容到粘贴板 function copyToClipboar ...

  4. Java 解决Emoji表情过滤问题(转载)

    本文作者 我是周洲 原文链接 https://blog.csdn.net/u012904383/article/details/79376707 本人使用的是第三种引入jar的方法 问题: Emoji ...

  5. git stash 缓存本地修改 简介

    当我们在使用git的时候,又是会有这种情况:当新的需求了的时候.我们需要为此需求新建一个分支,再次分支上进行修改,当经过测试,提交代码时,在将其合并到主分支,或生产分支上. 但是有时候也有失误的时候, ...

  6. 快速为不同 Git 平台配置用户

    在 ~ 目录下创建 config 文件可以为项目配置默认的用户信息,但如果希望经常切换,那么最好就是通过命令为项目单独设置用户. 我使用的 shell 是 zsh, 所以我在 ~/.zshrc 文件中 ...

  7. 解决spring-test中Feign问题: No qualifying bean of type 'org.springframework.cloud.openfeign.FeignContext' available

    问题现象: 启动测试类(含通过Feign远程调用的组件),报错: No qualifying bean of type 'org.springframework.cloud.openfeign.Fei ...

  8. mysqlslap压测

    mysqlslap 是MySQL自带的压测工具: -P --create-schema=test -S /tmp/mysql_sandbox18601.sock --number-of-queries ...

  9. python爬有道翻译

    在有道翻译页面中打开开发者工具,在Headers板块找到Request URL以及相应的data. import urllib.request import urllib.parse import j ...

  10. Java精通并发-wait与notify及线程同步系统总结

    notifyAll(): 在上两次中对于Object的wait()和notify()方法的官方doc进行了通读,上一次https://www.cnblogs.com/webor2006/p/11407 ...