传送门

\(A\)

咕咕咕

const int N=505;
int a[N],n,res;
int main(){
scanf("%d",&n);
fp(i,1,n<<1)scanf("%d",&a[i]);
sort(a+1,a+1+(n<<1));
fp(i,1,n)res+=a[(i<<1)-1];
printf("%d\n",res);
return 0;
}

\(B\)

考虑递归,记\(las\)表示画的上一个三角形的边长,\(now\)为现在的三角形的边长,如果\(now|las\),则再走\(las*2-las\)就可以到终点,否则我们可以走\(now\)的整数倍次,也就是说取个模,然后再计算下一个\(las\)和\(now\)就行了,复杂度为\(O(\log n)\)

建议画图理解

ll n,x,res,las,now,t;
int main(){
scanf("%lld%lld",&n,&x);
res=n,las=n-x,now=x;
while(now){
if(las%now==0){res+=(las<<1)-now;break;}
res+=(las/now*now)<<1,t=now,now=las%now,las=t;
}
printf("%lld\n",res);
return 0;
}

\(C\)

记\(f_{u,i}\)表示考虑\(u\)的子树内,且\(u\)子树内未被删去的点中深度最深的点里\(u\)的距离为\(i\),此时子树内剩余的点数最多为多少,转移只用合法的状态转移就是了

//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
using namespace std;
const int N=2005;
struct eg{int v,nx;}e[N<<1];int head[N],tot;
inline void add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
int f[N][N],g[N],mx[N],n,res,k;
void dfs(int u,int fa){
memset(f[u],0xef,sizeof(f[u]));
f[u][0]=1;
go(u)if(v!=fa){
dfs(v,u),memcpy(g,f[u],(max(mx[u],mx[v]+1)+1)<<2);
fp(i,0,mx[u])fp(j,0,mx[v])if(i+j+1<=k)
cmax(g[max(i,j+1)],f[u][i]+f[v][j]);
cmax(mx[u],mx[v]+1),memcpy(f[u],g,(mx[u]+1)<<2);
}
}
int main(){
scanf("%d%d",&n,&k);
for(R int i=1,u,v;i<n;++i)scanf("%d%d",&u,&v),add(u,v),add(v,u);
dfs(1,0);
fp(i,1,n)fp(j,0,min(mx[i],k))cmax(res,f[i][j]);
printf("%d\n",n-res);
return 0;
}

\(D\)

首先如果奇数的个数超过\(2\)就无解了,具体可以把回文串的相同看做连边,至少得连成一棵生成树,奇数的话中间的点就无法连边了,所以奇数大于\(2\)就\(gg\)

否则的话我们把奇数放到两边,并把最两边分别\(+1-1\),剩下的按顺序来就可以了

//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
using namespace std;
const int N=1e5+5;
int st[N],a[N],id[N],tt,n,m,top;
inline void Ot(){printf("%d\n",top);fp(i,1,top)printf("%d%c",st[i]," \n"[i==top]);}
int main(){
// freopen("testdata.in","r",stdin);
scanf("%d%d",&n,&m);
fp(i,1,m){
scanf("%d",&a[i]);
if(a[i]&1)id[++tt]=i;
}
if(tt>2)return puts("Impossible"),0;
if(tt>0)swap(a[1],a[id[1]]);if(tt>1)swap(a[m],a[id[2]]);
fp(i,1,m)printf("%d%c",a[i]," \n"[i==m]);
if(m==1){
st[++top]=1;
if(a[1]-1)st[++top]=a[1]-1;
}else{
--a[1],++a[m];
fp(i,1,m)if(a[i])st[++top]=a[i];
}
return Ot(),0;
}

\(E\)

好吧的确还是比较菜……

我们把\({a_i+b_i+a_j+b_j\choose a_i+a_j}\)变成从\((-a_i,-b_i)\)走到\((a_j,b_j)\)的方案数,那么可以直接通过\(O(MAX^2)\)的\(dp\)算出\(\sum_{i=1}^n\sum_{j=1}^n{a_i+b_i+a_j+b_j\choose a_i+a_j}\),减掉多算的就行了

//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
using namespace std;
const int P=1e9+7;
inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
R int res=1;
for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
return res;
}
const int N=2e5+5,M=5005,S=2005;
int a[N],b[N],fac[N],ifac[N],f[M][M],xmx,ymx,n,res;
inline int C(R int n,R int m){return m>n?0:1ll*fac[n]*ifac[m]%P*ifac[n-m]%P;}
void init(int n){
fac[0]=ifac[0]=1;
fp(i,1,n)fac[i]=mul(fac[i-1],i);
ifac[n]=ksm(fac[n],P-2);fd(i,n-1,1)ifac[i]=mul(ifac[i+1],i+1);
}
int main(){
// freopen("testdata.in","r",stdin);
scanf("%d",&n);
fp(i,1,n)scanf("%d%d",&a[i],&b[i]),cmax(xmx,a[i]),cmax(ymx,b[i]);
init((xmx+ymx)<<1);
fp(i,1,n)++f[S-a[i]][S-b[i]];
fp(i,S-xmx,S+xmx)fp(j,S-ymx,S+ymx)if(f[i][j])upd(f[i+1][j],f[i][j]),upd(f[i][j+1],f[i][j]);
fp(i,1,n)upd(res,f[S+a[i]][S+b[i]]);
fp(i,1,n)res=dec(res,C((a[i]+b[i])<<1,a[i]<<1));
printf("%d\n",mul(res,(P+1)>>1));
return 0;
}

\(F\)

很妙的转化

我们设一个新的序列\(Q\),其中\(Q_{P_i}=i\),那么操作可以变成“如果\(|Q_i-Q_{i+1}|\geq k\),则可以交换\(Q_i\)和\(Q_{i+1}\)”,我们需要让\(1\)这个元素在最左边,在满足这个条件的时候让\(2\)在最左边,在满足这个条件时让\(3\)在最左边……

假设在\(Q\)中存在\(i,j\)满足\(i<j\)且\(|Q_i-Q_j|<k\),那么在\(Q\)中\(Q_i\)在\(Q_j\)左边,任意次操作之后\(Q_i\)也一定还在\(Q_j\)的左边

此时我们可以从\(Q_i\)向\(Q_j\)连一条边,易知连完边之后的图一定是一个\(DAG\),那么我们找到这个\(DAG\)最小的拓扑序就好了

然而这样的话边数会爆炸

考虑优化,若存在\(i,j\)满足\(i<j\)且\(j-i<k\)且\(P_j<P_i\),则在图中会连边\(j,i\),若\(i\)满足\(i=\min(l,P_l>P_j,l\in[j-k+1,j-1])\),则对于任意\(l\),必定有连边\((j,l)\),同时也必定有连边\((i,l)\)!那么我们只需要连边\((j,i)\),即可满足拓扑的要求了。对于\(j\)的右边同样如此

用线段树优化即可

//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
using namespace std;
const int N=1e6+5,inf=0x3f3f3f3f;
struct eg{int v,nx;}e[N<<1];int head[N],tot;
inline void add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
inline int min(R int x,R int y){return x<y?x:y;}
struct node;typedef node* ptr;
struct node{
ptr lc,rc;int mn;
inline void upd(){mn=min(lc->mn,rc->mn);}
}E[N<<2],*nd=E,*rt;
priority_queue<int,vector<int>,greater<int> >q;int deg[N],pos[N],id[N],n,k;
void build(ptr &p,int l,int r){
p=++nd;if(l==r)return p->mn=inf,void();
int mid=(l+r)>>1;
build(p->lc,l,mid),build(p->rc,mid+1,r);
p->upd();
}
void update(ptr p,int l,int r,int x,int v){
if(l==r)return p->mn=v,void();
int mid=(l+r)>>1;
x<=mid?update(p->lc,l,mid,x,v):update(p->rc,mid+1,r,x,v);
p->upd();
}
int res;
void query(ptr p,int l,int r,int ql,int qr){
if(ql<=l&&qr>=r)return cmin(res,p->mn),void();
int mid=(l+r)>>1;
if(ql<=mid)query(p->lc,l,mid,ql,qr);
if(qr>mid)query(p->rc,mid+1,r,ql,qr);
}
int main(){
// freopen("testdata.in","r",stdin);
scanf("%d%d",&n,&k);
for(R int i=1,x;i<=n;++i)scanf("%d",&x),pos[x]=i;
build(rt,1,n);
for(R int i=n,l,r;i;--i){
l=max(pos[i]-k+1,1),r=pos[i]-1,res=inf;
if(l<=r)query(rt,1,n,l,r);if(res!=inf)add(pos[i],pos[res]),++deg[pos[res]];
l=pos[i]+1,r=min(pos[i]+k-1,n),res=inf;
if(l<=r)query(rt,1,n,l,r);if(res!=inf)add(pos[i],pos[res]),++deg[pos[res]];
update(rt,1,n,pos[i],i);
}
fp(i,1,n)if(!deg[i])q.push(i);
for(R int u,i=1;i<=n;++i){
u=q.top(),q.pop(),id[u]=i;
go(u)if(!--deg[v])q.push(v);
}
fp(i,1,n)printf("%d\n",id[i]);
return 0;
}

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

  1. AtCoder Grand Contest 001 C Shorten Diameter 树的直径知识

    链接:http://agc001.contest.atcoder.jp/tasks/agc001_c 题解(官方): We use the following well-known fact abou ...

  2. AtCoder Grand Contest 017 题解

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

  3. AtCoder Grand Contest 001 D - Arrays and Palindrome

    题目传送门:https://agc001.contest.atcoder.jp/tasks/agc001_d 题目大意: 现要求你构造两个序列\(a,b\),满足: \(a\)序列中数字总和为\(N\ ...

  4. Atcoder Grand Contest 001 F - Wide Swap(拓扑排序)

    Atcoder 题面传送门 & 洛谷题面传送门 咦?鸽子 tzc 来补题解了?奇迹奇迹( 首先考虑什么样的排列可以得到.我们考虑 \(p\) 的逆排列 \(q\),那么每次操作的过程从逆排列的 ...

  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 001] Tutorial

    Link: AGC001 传送门 A: …… #include <bits/stdc++.h> using namespace std; ; ]; int main() { scanf(& ...

  9. AtCoder Grand Contest 039 题解

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

随机推荐

  1. Challenge & Growth —— 从这里开始

    做有挑战的事情,就从这里开始. 忘记这本书现在在哪儿了,以前还以为能祖祖辈辈留传,现在只能借助 Nowcoder 了.Now coder,Forever thinker. 想以自以为最优美的 code ...

  2. P1777 帮助_NOI导刊2010提高(03)

    也许更好的阅读体验 \(\mathcal{Description}\) Bubu的书架乱成一团了!帮他一下吧! 他的书架上一共有n本书.我们定义混乱值是连续相同高度书本的段数.例如,如果书的高度是30 ...

  3. Dockerfile编写,以及设置一个自启动脚本

    FROM:指定基础镜像,必须为第一个命令 MAINTAINER: 维护者信息 RUN:构建镜像时执行的命令 ADD:将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问 ...

  4. Java中@SuppressWarnings("unchecked")的作用

    J2SE 提供的最后一个批注是 @SuppressWarnings.该批注的作用是给编译器一条指令,告诉它对被批注的代码元素内部的某些警告保持静默. 一点背景:J2SE 5.0 为 Java 语言增加 ...

  5. GRIT VIEW删除事件

    1.点选表格后找到事件 RowCommand 2.輸入gvGroupUser_RowCommand后双击                                        ------注分 ...

  6. DBShop后台RCE之曲线救国

    本文最早发布在朋友的公众号 黑客信徒 中,文章是自己写的 不存在抄袭  特此申明 --------------------- 前言 DBShop是一款基于ZendFramework2框架的电子商务系统 ...

  7. MongoDB 创建数据库和查询数据

    1.选择数据库  use test  2.创建用户  db.createUser({user:"test01",pwd:"12345",roles:[{role ...

  8. 直接插入排序算法(java)

    直接插入排序是将未排序的数据插入至已排好序序列的合适位置. 具体流程如下: 1.首先比较数组的前两个数据,并排序: 2.比较第三个元素与前两个排好序的数据,并将第三个元素放入适当的位置: 3.比较第四 ...

  9. jenkins+docker+git+harbor构建及代码回滚(未完)

    目录 一.部署 环境工作流程介绍 部署harbor 一.部署 前提环境说明 192.168.111.3 该机器为git本地仓库,及git远程仓库(git用户创建),及Harbor镜像仓库 192.16 ...

  10. Android笔记(八) Android中的布局——相对布局

    RelativeLayout又称为相对布局,也是一种常用的布局形式.和LinearLayout的排列规则不同,RelativeLayout显得更加随意一下,它通常通过相对定位 的方式让控件出现在布局的 ...