最近一周都在刷历年的APIO题,发现网上APIO的题解并不是很多,正好做了感觉这些题都挺有意思的,于是准备发一个APIO2007到2015年这9年题目的题解集合(好像还没人做过这件事情……)APIO给我的感觉是有很多题比较考思维,也有写起来需要很多细节的题。有意思的是,APIO并没有出现过中国特色数据结构(给你一个序列,支持XXXX操作,来个可持久化树套树看出题人心情带不带垃圾回收……),尽管2010年是中国出题;相反,APIO中很多题目是贪心和DP,这也是能够充分考验一个选手的分析能力的题目类型。
另外:之后的题目中,如果出现了【上古预警】,则代表这些题目是作者很早的时候做的,记忆可能比较搓,方法比较笨,代码风格可能比较丑……
#include
#include
#include
#include
#include
#include
#include
using namespace std;
//基本思路:判断无解:首先如果在图中一开始就有层数差距大于1,则不可能成功。
//否则,肯定是能成功的。
//这样我们可以对左右的“纯”和“不纯”进行讨论
int n,maxd=0,mind=999999999,deep[100005]={0},d[100005]={0},l[100005]={0},r[100005]={0};
int f[100005]={0};
bool high[100005]={0};
int pure[100005]={0};
void input()
{scanf("%d",&n);
for(int i=1;i<=n;i++)
{scanf("%d%d",&l[i],&r[i]);
}
}
void dfs(int x,int depth)
{deep[x]=depth;
//cout<1){printf("-1");exit(0);}//基本避免了要写手工栈的情况(显然如果都在最下面一层那么层数是log级的绝对不会爆栈,如果不是那么必然中间会出现不满足的情况。现在只有类似哈夫曼树的感觉可以卡爆)
}
if(l[x]!=-1)dfs(l[x],depth+1);
if(r[x]!=-1)dfs(r[x],depth+1);
}
void dfs2(int x)
{high[x]=0,pure[x]=0;
if(l[x]==-1||r[x]==-1)
{//cout<<"!!!"<1){printf("-1");return 0;}
else if(maxd==mind){printf("0");return 0;}
//cout<
#include
#include
#include
#include
#include
#include
#include
using namespace std;
long long ans=0,heapnum=0,n,k,a[100005]={0},pre[100005]={0},nxt[100005]={0};
long long eliminate[100005]={0};
long long s[100005]={0},hpos[100005]={0};
long long f[305][305]={0};
struct node{long long x,pos;}heap[500005]={0};
void heapup()
{long long i=heapnum;
while(i>1&&heap[i].xheap[j].x)swap(hpos[heap[i].pos],hpos[heap[j].pos]),swap(heap[i],heap[j]),i=j;
else break;
}
}
void del()
{heap[1]=heap[heapnum],hpos[heap[heapnum].pos]=1;
heapnum--;
heapdown();
}
void input()
{scanf("%lld%lld",&n,&k);
for(long long i=1;i<=n;i++)
scanf("%lld",&a[i]);
n--;
for(long long i=1;i<=n;i++)
{s[i]=a[i+1]-a[i];
setheap(s[i],i);
}
for(long long i=1;i<=n;i++)
pre[i]=i-1,nxt[i]=i+1;
nxt[n]=pre[1]=0;
}
void solve()
{//heap[0].x=999999999999999LL;
for(long long i=1;i<=k;i++)//一次次进行处理
{node x=heap[1];del();
while(eliminate[x.pos]||x.x!=s[x.pos])x=heap[1],del();
ans+=x.x;
//heap[fa].eliminate=heap[son].eliminate=heap[1].eliminate=1;
eliminate[x.pos]=eliminate[pre[x.pos]]=eliminate[nxt[x.pos]]=1;
if(pre[x.pos]&&nxt[x.pos])
{eliminate[x.pos]=0;
s[x.pos]=s[pre[x.pos]]+s[nxt[x.pos]]-s[x.pos];
pre[x.pos]=pre[pre[x.pos]],nxt[pre[x.pos]]=x.pos;
nxt[x.pos]=nxt[nxt[x.pos]],pre[nxt[x.pos]]=x.pos;
setheap(s[x.pos],x.pos);
}
else if(!pre[x.pos])pre[nxt[nxt[x.pos]]]=0;
else if(!nxt[x.pos])nxt[pre[pre[x.pos]]]=0;
}
}
int main()
{input();
solve();
printf("%lld",ans);
fclose(stdin);
fclose(stdout);
return 0;
}
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int cnt=0,ans=0,n,c,a,b,d,f[50005][33]={0},num[50005][33]={0},h[50005]={0};
struct node{int st,love,hate;}child[50005];
struct nodf{int next,to;}edge[50005];
void Addedge(int x,int y)
{cnt++,edge[cnt].to=y,edge[cnt].next=h[x],h[x]=cnt;
}
void Dfs(int x,int status,int depth)
{if(depth>=5)
{if(((child[x].hate&status)!=child[x].hate)||(child[x].love&status))num[child[x].st][status]++;
return;
}
Dfs(x,status,depth+1);
Dfs(x,status|(1<>(i-1)),r=(1<<(5-i))-1;
if((j&r)==q)
{f[i][j]=max(f[i-1][(j<<1)&31],f[i-1][((j<<1)&31)+1])+num[i][j];
}
else f[i][j]=0;
}
}
else if(i+3>(n-i+1))==q)
{f[i][j]=max(f[i-1][(j<<1)&31],f[i-1][((j<<1)&31)+1])+num[i][j];
}
else f[i][j]=0;
}
}
}
for(int i=0;i<=31;i++)
{ans=max(ans,f[n][i]);
}
}
void Solve()
{for(int i=0;i<=1;i++)
for(int j=0;j<=1;j++)
for(int k=0;k<=1;k++)
for(int l=0;l<=1;l++)
{for(int q=0;q<=31;q++)
f[0][q]=0;
DP(i*8+j*4+k*2+l);
}
printf("%d\n",ans);
}
int main()
{Input();
Solve();
return 0;
}