传送门

\(A\)

肯定是后面每两个陪最前面一个最优

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

\(B\)

首先染色肯定是后面的覆盖前面的,那么我们从后往前做,并对每个点记录\(d_i\)从这个点还能延伸多少,只有当\(d_i\)增大的时候才考虑从它开始更新,因为所有的\(d\)都很小,所以每个点被更新不会超过\(d_i\)次,总复杂度为\(O(d_in)\)

  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. struct node{int u,d,c;}E[N];
  14. int d[N],c[N],q[N],n,m,Q;
  15. void solve(int S,int dis,int col){
  16. int h=1,t=0,u;
  17. q[++t]=S;
  18. while(h<=t){
  19. u=q[h++];if(!c[u])c[u]=col;
  20. go(u)if(cmax(d[v],d[u]-1))q[++t]=v;
  21. }
  22. }
  23. int main(){
  24. scanf("%d%d",&n,&m);
  25. fp(i,1,n)d[i]=-1;
  26. for(R int i=1,u,v;i<=m;++i)scanf("%d%d",&u,&v),add(u,v),add(v,u);
  27. scanf("%d",&Q);
  28. fp(i,1,Q)scanf("%d%d%d",&E[i].u,&E[i].d,&E[i].c);
  29. fd(i,Q,1)if(cmax(d[E[i].u],E[i].d))solve(E[i].u,E[i].d,E[i].c);
  30. fp(i,1,n)printf("%d\n",c[i]);
  31. return 0;
  32. }

\(C\)

让最终的序列长成形如\(p_1,p_2,p_3,...,p_n,1,2,3,...,n\)的形式,那么发现合法的子序列个数就是\(p\)中递增子序列个数\(-1\)

那么我们\(++n\),然后用一个类似倍增的思想来维护。发现空集时递增子序列个数为\(1\),在后面加上\(n+1\)子序列个数\(\times 2\),在前面加上\(n+1\)子序列个数\(+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. typedef long long ll;
  11. deque<int>st;ll n,k;int pos;
  12. int main(){
  13. scanf("%lld",&n);++n;
  14. while((1ll<<pos)<=n)++pos;
  15. fd(i,pos-2,0){
  16. st.push_back(++k);
  17. if(n>>i&1)st.push_front(++k);
  18. }
  19. printf("%d\n",k<<1);
  20. fp(i,0,k-1)printf("%d ",st[i]);
  21. fp(i,1,k)printf("%d ",i);
  22. return 0;
  23. }

\(D\)

首先,我们发现如果能交换\(ab\)和\(ac\),那么可以在不改变其他位置的情况下交换\(bc\),所以如果我们把所有可以交换的连一条边,则一个连通块中所有的点都可以互换位置,连通块内部的答案直接算就可以了

然后考虑连边,对于每个点\(u\),设它这种颜色对应的重量最小的点为\(mn\),有两种情况\(u\)能和\(mn\)联通,一种是直接连边,一种是找到一个与它们颜色不同的\(v\)然后连边\((u,v)\)和\((v,mn)\)。那么如果\(u\neq mn\)且能直接连边就连边,否则找到一个与它们颜色不同且重量最小的点\(v\)尝试与它连边。不难发现最终所有连过边的点都和重量最小的点在同一个连通块中,那么计算一下就行了

  1. //quming
  2. #include<bits/stdc++.h>
  3. #define R register
  4. #define fi first
  5. #define se second
  6. #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
  7. #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
  8. #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
  9. template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
  10. template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
  11. using namespace std;
  12. const int P=1e9+7;
  13. inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
  14. inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
  15. inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
  16. inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
  17. int ksm(R int x,R int y){
  18. R int res=1;
  19. for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
  20. return res;
  21. }
  22. const int N=2e5+5;
  23. typedef pair<int,int> pi;
  24. int fac[N],ifac[N],fa[N],mn[N],cnt[N];pi c[N];
  25. int n,x,y,pos,sz,res;
  26. inline int find(R int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
  27. int main(){
  28. scanf("%d%d%d",&n,&x,&y);
  29. fp(i,1,n)scanf("%d%d",&c[i].se,&c[i].fi);
  30. sort(c+1,c+1+n);
  31. pos=2;
  32. while(pos<=n&&c[pos].se==c[1].se)++pos;
  33. if(pos>n)return puts("1"),0;
  34. fd(i,n,1)mn[c[i].se]=i,fa[i]=i;
  35. fd(i,n,1){
  36. if(i!=mn[c[i].se]&&c[i].fi+c[mn[c[i].se]].fi<=x)
  37. fa[find(i)]=find(mn[c[i].se]);
  38. else if(c[i].se!=c[1].se&&c[i].fi+c[1].fi<=y)
  39. fa[find(i)]=find(1);
  40. else if(c[i].se!=c[pos].se&&c[i].fi+c[pos].fi<=y)
  41. fa[find(i)]=find(pos);
  42. }
  43. fac[0]=ifac[0]=1;fp(i,1,n)fac[i]=mul(fac[i-1],i);
  44. ifac[n]=ksm(fac[n],P-2);fd(i,n-1,1)ifac[i]=mul(ifac[i+1],i+1);
  45. fp(i,1,n)if(find(i)==find(1))++sz,++cnt[c[i].se];
  46. res=fac[sz];
  47. fp(i,1,n)res=mul(res,ifac[cnt[i]]);
  48. printf("%d\n",res);
  49. return 0;
  50. }

\(F\)

感觉司公子说的比\(yyb\)说的好懂一点……那我这里就说一下司公子的写法吧……

方便起见先默认\(a_i=i\)

首先,显然\(i\leq b_i\leq 2n-i\)

其次,我们考虑加入两个新的数字,那么中位数要么不变,要么变成前驱或者后继

所以会有两个性质

\(1.i\leq b_i\leq 2n-i\)

\(2.\),不存在\(i<j\),使得\(b_j<b_i<b_{j+1}\)或者\(b_j>b_i>b_{j+1}\)

我们可以认为假设有一个\(S\)表示所有合法的\(b_i\)的取值的集合,首先肯定有\(b_n=n\),那么如果我们倒着构造\(b\),且正在考虑到\(b_i\),第一个性质代表我们可以往\(S\)中加入\(i\)和\(2n-i\),第二个性质说明如果选定了\(b_i\),那么\(S\)中所有值在\(b_i\)和\(b_{i+1}\)之间的数(不含端点)都应该被删去(因为根据性质\(2\)显然前面的数中是不能存在这样的数的)

\(ps:\)或者上面的第二点也可以理解为,如果\(b_{i}\neq b_{i+1}\)说明\(b_{i+1}\)必定是前\(2i+1\)个数中\(b_i\)的前驱或后继,那么在它们区间内的数显然会妨碍它们成为前驱或后继,所以在\(a\)中都不能存在

然后我们来考虑一下,按照上面这个规则构造出来的\(b\)是否全部合法,也就是说\(S\)里面所有的数只有一个必要性,如何证明它们的充分性

考虑从\(b_{i+1}\)到\(b_i\)的过程,如果\(b_{i+1}>b_i\),那么我们删去前\(2i+1\)个数中比\(b_{i+1}\)大的最小的两个数,那么我们可以取到合法的\(b_i\)的最小值,同理如果\(b_{i+1}<b_i\)可以取到最大值,而\(b_{i}=b_{i+1}\)的话,我们只要删掉前\(2i+1\)个数中比\(b_i\)大的最小的数和比\(b_i\)小的最大的数就可以取到最大最小值了

然后接下来就是计算方案了,记\(f[i][j][k]\)表示倒序考虑\(b\),考虑了\(i\)个数,合法的取值个数为\(j\),且取了这些值中第\(k\)个的方案数,转移枚举一下下一个数取了合法取值中第几个就行了

记得有一个问题就是实际上\(a\)可能会有相等的情况,那么性质一能不能拓展要看情况

说真的还是看代码比较好理解……

  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=105;
  21. int a[N],f[N][N][N],n,res;
  22. int main(){
  23. scanf("%d",&n);
  24. fp(i,1,n+n-1)scanf("%d",&a[i]);
  25. sort(a+1,a+n+n);
  26. f[1][1][1]=1;
  27. fp(i,1,n-1)fp(j,1,n+n-1)fp(k,1,j)if(f[i][j][k]){
  28. R int tj=j,tk=k;
  29. if(a[n+i]!=a[n+i-1])++tj;
  30. if(a[n-i]!=a[n-i+1])++tj,++tk;
  31. fp(h,1,tj){
  32. if(h<tk)upd(f[i+1][tj-(tk-h-1)][h],f[i][j][k]);
  33. if(h>tk)upd(f[i+1][tj-(h-tk-1)][tk+1],f[i][j][k]);
  34. if(h==tk)upd(f[i+1][tj][h],f[i][j][k]);
  35. }
  36. }
  37. fp(i,1,n+n-1)fp(j,1,i)upd(res,f[n][i][j]);
  38. printf("%d\n",res);
  39. return 0;
  40. }

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

  1. AtCoder Grand Contest 012

    AtCoder Grand Contest 012 A - AtCoder Group Contest 翻译 有\(3n\)个人,每一个人有一个强大值(看我的假翻译),每三个人可以分成一组,一组的强大 ...

  2. AtCoder Grand Contest 012 A

    A - AtCoder Group Contest Time limit : 2sec / Memory limit : 256MB Score : 300 points Problem Statem ...

  3. AtCoder Grand Contest 012 A - AtCoder Group Contest(贪心)

    Time limit : 2sec / Memory limit : 256MB Score : 300 points Problem Statement There are 3N participa ...

  4. AtCoder Grand Contest 012 C:Tautonym Puzzle

    题目传送门:https://agc012.contest.atcoder.jp/tasks/agc012_c 题目翻译 如果一个字符串是好的,那么这个字符串的前半部分和后半部分肯定一模一样.比如\(a ...

  5. AtCoder Grand Contest 012 D:Colorful Balls

    题目传送门:https://agc012.contest.atcoder.jp/tasks/agc012_d 题目翻译 给你一排一共\(N\)个球,每个球有一个颜色\(c_i\)和一个重量\(w_i\ ...

  6. AtCoder Grand Contest 012 B - Splatter Painting(dp)

    Time limit : 2sec / Memory limit : 256MB Score : 700 points Problem Statement Squid loves painting v ...

  7. AtCoder Grand Contest 017 题解

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

  8. Atcoder Grand Contest 054 题解

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

  9. AtCoder Grand Contest 030题解

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

随机推荐

  1. 日志之slf4j和logback日志系统(二)

    这篇文章我们讲一下,如何使用slf4j和logback组合来搭建一套日志系统. 介绍 如果我们的系统是新系统,也就是之前没有引入其他的日志工具,那么只需要引入,如果之前已经用了common-loggi ...

  2. ADO.Net和SqlHelper封装

    1.什么是ADO.Net 简单来讲,ADO.NET是用于和数据源打交道的.Net结束,是一组向.NET程序员公开数据访问服务的类   2.ADO.NET的组成部分和对象模型 (1)ADO.NET的两个 ...

  3. C#破解dll

    使用反编译工具对dll文件进行反编译,找到校验过期的相关代码,反编译工具可以使用ILSpy或Reflector; 使用ildasm.exe工具将dll导出成il文本文件,在该文件中找到相关的代码进行修 ...

  4. C++项目链接出错, error LNK2019: 无法解析的外部符号 __imp_xxxx_Allocate,该符号在函数 "xxxx" (xxxx) 中被引用

    1 错误提示 error LNK2019: 无法解析的外部符号 __imp_FreeImage_Allocate,该符号在函数 "public: bool __cdecl colmap::B ...

  5. python day 8: re模块补充,导入模块,hashlib模块,字符串格式化,模块知识拾遗,requests模块初识

    目录 python day 8 1. re模块补充 2. import模块导入 3. os模块 4. hashlib模块 5. 字符串格式:百分号法与format方法 6. 模块知识拾遗 7. req ...

  6. 'adb' 不是内部或外部命令,也不是可运行的程序 或批处理文件—解决方法

    Windows键 + R → 输入cmd → 输入adb,提示“adb不是内部或外部命令,也不是可运行的程序 或批处理文件“,错误信息如下: 解决方法: 此电脑(右击)→ 属性 → 高级系统设置 → ...

  7. 解决Vivado XSDK在Ubuntu系统上自带UART Terminal Crash问题

    在Ubuntu 18.04 LTS系统上使用某些版本的Vivado XSDK的Eclipse IDE中自带的串口Terminal会有Crash的问题.Xilinx的XSDK的Terminal插件是用的 ...

  8. Github的fork进行同步

    最近项目要求每个开发人员都有自己fork,需要在自己的fork下进行开发.这样就涉及的到fork和原仓库的同步问题. 在网上查找到fork和原仓库同步的方法,如下转载自网上查找的内容,使用终端命令行进 ...

  9. 《Clean Code》读书笔记——第二周

    本周我阅读了<Clean Code>. “神在细节中!”,建筑家范德罗如是说.他当然专注于基于宏伟构架之上的永恒建筑形式,他也同样为自己设计的建筑挑选门把手.同样软件开发也是这样,小处见大 ...

  10. Delphi-RzDbgrid-绘制表格式设置某行颜色或者其他格式-以及隔行换色的属性

    参考文章:https://www.cnblogs.com/OSKnown/p/8568740.html 在DbgridEh和原生的Dbgrid直接在DrawColumnCell事件中写重绘代码就好了, ...