2015 Multi-University Training Contest 3
1001 Magician
线段树。根据奇偶性分成4个区间。维护子列和最大值。
想法很简单。但是并不好写。
首先初始化的时候对于不存在的点要写成-INF。
然后pushup的时候。对于每个区间要考虑四个情况。
例如sum01。
他可能是左子树的sum01右子树的sum01。
或者左子树的sum01+右子树的sum01。
或者左子树的sum00+右子树的sum11。
最后注意query函数的写法。
如果在递归的时候就讨论奇偶性。
下层的每个区间都要被重复调用。而且是层数的指数级。
于是参考学习了一种直接把子区间合并成一个区间类型返回的方法。
合成目标区间后再讨论奇偶性。
【其实pushup和query可以写好看些。好不容易调对。懒得改了。】
# include <iostream>
# include <cstdio>
# include <algorithm>
using namespace std;
typedef long long LL;
# define maxn
# define INF (LL)
LL a[maxn]; struct node
{
int l,r;
LL sum00,sum01,sum10,sum11;
}tree[*maxn]; void pushup(int i)
{
tree[i].sum00=tree[i].sum01=tree[i].sum10=tree[i].sum11=-INF;
tree[i].sum00=max(tree[i].sum00,tree[*i].sum00+tree[*i+].sum10);
tree[i].sum00=max(tree[i].sum00,tree[*i].sum01+tree[*i+].sum00);
tree[i].sum00=max(tree[i].sum00,tree[*i].sum00);
tree[i].sum00=max(tree[i].sum00,tree[*i+].sum00);
tree[i].sum01=max(tree[i].sum01,tree[*i].sum00+tree[*i+].sum11);
tree[i].sum01=max(tree[i].sum01,tree[*i].sum01+tree[*i+].sum01);
tree[i].sum01=max(tree[i].sum01,tree[*i].sum01);
tree[i].sum01=max(tree[i].sum01,tree[*i+].sum01);
tree[i].sum10=max(tree[i].sum10,tree[*i].sum10+tree[*i+].sum10);
tree[i].sum10=max(tree[i].sum10,tree[*i].sum11+tree[*i+].sum00);
tree[i].sum10=max(tree[i].sum10,tree[*i].sum10);
tree[i].sum10=max(tree[i].sum10,tree[*i+].sum10);
tree[i].sum11=max(tree[i].sum11,tree[*i].sum10+tree[*i+].sum11);
tree[i].sum11=max(tree[i].sum11,tree[*i].sum11+tree[*i+].sum01);
tree[i].sum11=max(tree[i].sum11,tree[*i].sum11);
tree[i].sum11=max(tree[i].sum11,tree[*i+].sum11);
return;
} void buildtree(int i,int l,int r)
{
tree[i].l=l; tree[i].r=r;
if(l<r)
{
buildtree(*i,l,(l+r)/);
buildtree(*i+,(l+r)/+,r);
pushup(i);
}
else
{
if(l%)
{
tree[i].sum11=a[l];
tree[i].sum10=tree[i].sum01=tree[i].sum00=-INF;
}
else
{
tree[i].sum00=a[l];
tree[i].sum10=tree[i].sum01=tree[i].sum11=-INF;
}
}
return;
} void update(int i,int p,int v)
{
if(tree[i].l==tree[i].r)
{
if(p%) tree[i].sum11=v;
else tree[i].sum00=v;
}
else
{
if(p<=(tree[i].l+tree[i].r)/) update(*i,p,v);
else update(*i+,p,v);
pushup(i);
}
return;
} node query(int i,int l,int r)
{
if(tree[i].l>=l&&tree[i].r<=r) return tree[i];
if(r<=(tree[i].l+tree[i].r)/) return query(*i,l,r);
if(l>=(tree[i].l+tree[i].r)/+) return query(*i+,l,r);
node t,t1,t2;
t1=query(*i,l,r);
t2=query(*i+,l,r);
t.sum00=max(t1.sum00,t2.sum00);
t.sum00=max(t.sum00,t1.sum00+t2.sum10);
t.sum00=max(t.sum00,t1.sum01+t2.sum00);
t.sum01=max(t1.sum01,t2.sum01);
t.sum01=max(t.sum01,t1.sum00+t2.sum11);
t.sum01=max(t.sum01,t1.sum01+t2.sum01);
t.sum10=max(t1.sum10,t2.sum10);
t.sum10=max(t.sum10,t1.sum10+t2.sum10);
t.sum10=max(t.sum10,t1.sum11+t2.sum00);
t.sum11=max(t1.sum11,t2.sum11);
t.sum11=max(t.sum11,t1.sum10+t2.sum11);
t.sum11=max(t.sum11,t1.sum11+t2.sum01);
return t;
} int main(void)
{
int T; cin>>T;
while(T--)
{
int n,m; scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%I64d",a+i);
buildtree(,,n);
while(m--)
{
int type,x,y; scanf("%d%d%d",&type,&x,&y);
if(type) update(,x,y);
else
{
node tem=query(,x,y);
LL ans=-INF;
ans=max(ans,tem.sum00);
ans=max(ans,tem.sum01);
ans=max(ans,tem.sum10);
ans=max(ans,tem.sum11);
printf("%I64d\n",ans);
}
}
}
return ;
}
Aguin
1002 RGCDQ
先枚举1000000内所有质因数。
然后统计区间内每个数的质因数个数。
注意到最大只有7。
对于因子个数为1-7的数的个数处理一下前缀和。
对于每个询问。算区间内因子数分别为1-7的数的个数。
找到最大的gcd就是答案。
# include <iostream>
# include <cstdio>
# include <cstring>
# include <algorithm>
# include <vector>
using namespace std;
# define maxn
bool tag[maxn]={,};
int prime[],cnt[maxn]={},presum[][maxn]={}; int main(void)
{
int t=;
for(int i=;i<maxn/;i++)
{
if(!tag[i]) prime[++t]=i;
for(int j=;j<=t&&i*prime[j]<maxn;j++)
{
tag[i*prime[j]]=;
if(i%prime[j]==) break;
}
}
for(int i=;i<=t;i++)
for(int j=;prime[i]*j<=maxn;j++)
cnt[prime[i]*j]++;
for(int i=;i<=maxn;i++)
for(int j=;j<=;j++)
{
presum[j][i]=presum[j][i-];
if(cnt[i]==j) presum[j][i]++;
}
int T; cin>>T;
while(T--)
{
int l,r; scanf("%d%d",&l,&r);
int mark[]={};
for(int i=;i<;i++) mark[i]=max(,presum[i][r]-presum[i][l-]);
if(mark[]>=) printf("7\n");
else if(mark[]>=) printf("6\n");
else if(mark[]>=) printf("5\n");
else if(mark[]>=) printf("4\n");
else if(mark[]>=||mark[]&&mark[]) printf("3\n");
else if(mark[]>=||mark[]&&mark[]||mark[]&&mark[]) printf("2\n");
else printf("1\n");
}
return ;
}
Aguin
1004 Painter
看成R和B的两张图。
统计R\斜边上与B/斜边上的连续染色段数即为答案。
# include <iostream>
# include <cstdio>
# include <cstring>
using namespace std;
# define CLR(x) memset(x,,sizeof(x))
char map[][];
int R[][],B[][]; int main(void)
{
int T; cin>>T;
while(T--)
{
CLR(map); CLR(R); CLR(B);
int n; scanf("%d",&n);
for(int i=;i<n;i++) scanf("%s",map[i]);
int len=strlen(map[]);
for(int i=;i<n;i++)
for(int j=;j<len;j++)
{
if(map[i][j]=='R') R[i][j]=;
else if(map[i][j]=='B') B[i][j]=;
else if(map[i][j]=='G') R[i][j]=B[i][j]=;
}
int ans=;
for(int i=-n;i<len;i++)
{
int flag=;
for(int j=;j<n&&i+j<len;j++)
{
if(i+j<) continue;
if(!flag&&R[j][i+j]) {ans++;flag=;}
if(!R[j][i+j]) flag=;
}
}
for(int i=;i<n+len-;i++)
{
int flag=;
for(int j=;j<len&&i-j>=;j++)
{
if(i-j>=n) continue;
if(!flag&&B[i-j][j]) {ans++;flag=;}
if(!B[i-j][j]) flag=;
}
}
printf("%d\n",ans);
}
return ;
}
Aguin
1005 Fan Li
1006 Beautiful Set
1007 Hope
1008 Solve this interesting problem
暴搜可行 证明不会。
l<0跳。l>r-l跳。r>现有答案跳。
搜[l,2*r-l]的时候注意死循环。
# include <iostream>
# include <cstdio>
# include <algorithm>
using namespace std;
typedef long long LL;
LL ans; void dfs(LL l,LL r)
{
if(l==)
{
if(ans==-) ans=r;
else ans=min(ans,r);
return;
}
if(l<) return;
if(ans!=-&&r>=ans) return;
if(r>*l) return;
if(r>l) dfs(l,*r-l);
dfs(*l-r-,r);
dfs(*l-r-,r);
dfs(l,*r-l+);
return;
} int main(void)
{
LL l,r;
while((scanf("%I64d%I64d",&l,&r))!=EOF)
{
ans=-;
dfs(l,r);
printf("%I64d\n",ans);
}
return ;
}
Aguin
1009 Boring Class
1010 Crazy Bobo
按官方题解。
把每条边变成从w大的点到w小的点的有像边。
以u为min的目标集就是能走到u的点的集合。
花了较长的时间思考这个问题。
换一种说法。
其实就是对于一个已经确定最小值u的目标集S。
点v在S中当且仅当v能通过递减的路到达u。
简要说明一下必要性和充分性。
随手画了个图。
任意取一条链。比方X。它必然有一个端点x1。
只要说明离x1最近的点x2小于x1。然后考虑去掉x1的图。归纳即可得到上述结论。
考虑S中比x1小的最大的点p的位置。
如果x2就是p。那么它比x1小。
如果x2不是p。那么由于x2离x1最近。无论p在什么位置。x2都在p-x1的链上。
根据S的定义。x2小于x1。
反之。如果所有链都是以递减的顺序通向u的。
那么考虑图中的最大点。其必然在一条链的端点。
比方仍取X链。x1是最大点。
最大点给集合带来的约束条件只有一条。
那就是最大点到次大点的路径上的所有点小于最大点。
但是所有点都小于最大点。所以这个条件必然成立。
也就是说原来的点属于S集等价于去掉最大点后的所有点属于S集合。
而去掉x1后的最大点可能是x2或者是其他链的端点。
只要不断从端点去掉最大点。归纳即可证明原来的所有点属于S集。
证明这个之后。树dp即可。
# include <iostream>
# include <cstdio>
# include <cstring>
# include <algorithm>
# include <vector>
using namespace std;
# define maxn
int w[maxn],dp[maxn];
vector<int> edge[maxn]; struct V
{
int id,w;
} node[maxn]; bool cmp(V a,V b)
{
return a.w>b.w;
} int main(void)
{
int n;
while((scanf("%d",&n))!=EOF)
{
memset(edge,,sizeof(edge));
for(int i=;i<=n;i++)
{
scanf("%d",w+i);
node[i].id=i;
node[i].w=w[i];
}
for(int i=;i<n;i++)
{
int a,b; scanf("%d%d",&a,&b);
if(w[a]>w[b]) edge[b].push_back(a);
else if(w[a]<w[b]) edge[a].push_back(b);
}
sort(node+,node++n,cmp);
int ans=;
for(int i=;i<=n;i++)
{
int pos=node[i].id;
dp[pos]=;
for(int j=;j<edge[pos].size();j++)
dp[pos]+=dp[edge[pos][j]];
ans=max(dp[pos],ans);
}
printf("%d\n",ans);
}
return ;
}
Aguin
1011 Work
签到题。dfs一遍即可。
# include <iostream>
# include <cstdio>
# include <cstring>
# include <vector>
using namespace std;
int ind[],cnt[];
vector <int> edge[]; void dfs(int x)
{
cnt[x]=edge[x].size();
for(int i=;i<edge[x].size();i++)
{
dfs(edge[x][i]);
cnt[x]+=cnt[edge[x][i]];
}
return;
} int main(void)
{
int n,k;
while((scanf("%d%d",&n,&k))!=EOF)
{
memset(ind,,sizeof(ind));
memset(cnt,,sizeof(cnt));
for(int i=;i<=n;i++) edge[i].clear();
for(int i=;i<n;i++)
{
int u,v; scanf("%d%d",&u,&v);
edge[u].push_back(v);
ind[v]++;
}
for(int i=;i<=n;i++) if(!ind[i]) dfs(i);
int ans=;
for(int i=;i<=n;i++) if(cnt[i]==k) ans++;
printf("%d\n",ans);
}
return ;
}
Aguin
2015 Multi-University Training Contest 3的更多相关文章
- 2015 Multi-University Training Contest 8 hdu 5390 tree
tree Time Limit: 8000ms Memory Limit: 262144KB This problem will be judged on HDU. Original ID: 5390 ...
- 2015 UESTC Winter Training #8【The 2011 Rocky Mountain Regional Contest】
2015 UESTC Winter Training #8 The 2011 Rocky Mountain Regional Contest Regionals 2011 >> North ...
- 2015 UESTC Winter Training #7【2010-2011 Petrozavodsk Winter Training Camp, Saratov State U Contest】
2015 UESTC Winter Training #7 2010-2011 Petrozavodsk Winter Training Camp, Saratov State U Contest 据 ...
- Root(hdu5777+扩展欧几里得+原根)2015 Multi-University Training Contest 7
Root Time Limit: 30000/15000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Su ...
- 2015 Multi-University Training Contest 6 solutions BY ZJU(部分解题报告)
官方解题报告:http://bestcoder.hdu.edu.cn/blog/2015-multi-university-training-contest-6-solutions-by-zju/ 表 ...
- HDU 5360 Hiking(优先队列)2015 Multi-University Training Contest 6
Hiking Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total S ...
- hdu 5288 OO’s Sequence(2015 Multi-University Training Contest 1)
OO's Sequence Time Limit: 4000/2000 MS (Jav ...
- HDU5294 Tricks Device(最大流+SPFA) 2015 Multi-University Training Contest 1
Tricks Device Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) To ...
- hdu 5416 CRB and Tree(2015 Multi-University Training Contest 10)
CRB and Tree Time Limit: 8000/4000 MS (J ...
- 2015多校联合训练赛 hdu 5308 I Wanna Become A 24-Point Master 2015 Multi-University Training Contest 2 构造题
I Wanna Become A 24-Point Master Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 ...
随机推荐
- hdu 2829 Lawrence(斜率优化DP)
题目链接:hdu 2829 Lawrence 题意: 在一条直线型的铁路上,每个站点有各自的权重num[i],每一段铁路(边)的权重(题目上说是战略价值什么的好像)是能经过这条边的所有站点的乘积之和. ...
- Scala内部类
注意:Java内部类从属于外部类,而Scala内部类从属于对象(外部类的实例本身).
- php 问答
1,如何设置长生命期的session ? 将 session.cookie_lifetime ,session.gc_maxlifetime 的时间设置长一点. 2,为什么初始化session的时候报 ...
- svn checkout操作
svn checkout https://svn.com/svn/project 该操作从svn服务器上拉代码下来,并且建立本地和远端的文件对应,状态的关联. 1,和export的区别 svn检出操作 ...
- python setup.py install 报错ImportError: No module named setuptools
学习光荣之路python课程时,使用python setup.py install安装其他模块时,第一次安装某模块成功了.安装另一模块却报错ImportError: No module named s ...
- perl Mail::Sender模块发送邮件
#!/usr/bin/perl -w use strict; use Mail::Sender; ; ){ my $sender = Mail::Sender->new({ smtp => ...
- Fighting For 2017 Season Contest 1
比赛地址[https://vjudge.net/contest/147011#problem/A].960626 题目一:[http://codeforces.com/problemset/probl ...
- 关于reportng生成的测试报告不按测试执行顺序的解决办法
需要修改TestResultComparator类的源码,源码自己去reportng官网http://reportng.uncommons.org/下载,因为reportng默认是按字母先后顺序进行排 ...
- HTML link标签media参数
写html这么久了,今天才发现link标签还有个media参数,赶紧把它补回来,虽然现在没有用到,但是不能不知道它 定义和用法 media 属性规定被链接文档将显示在什么设备上. media 属性用于 ...
- proc中tran的一般处理
存储过程事物的处理 一般情况在proc中判断的处理我们都采用 ) begin select '错误' return end 而在tran中我们最好用抛异常的方式 begin try begin SET ...