【比赛】百度之星2017 初赛Round A
第一题
题意:给定多组数据P,每次询问P进制下,有多少数字B满足条件:只要数位之和是B的倍数,该数字就是B的倍数。
题解:此题是参考10进制下3和9倍数的特殊性质。
对于10进制,ab=10*a+b=9*a+(a+b),所以9的约数都有此性质。
对于P进制,ab=p*a+b=(p-1)a+(a+b),所以p-1的约数都有此性质。
对于P,计算P-1的约数个数即为答案。
★第二题
题意:给定L的关系(L<=10^5),关系表示为xi=xj或xi≠xj,将数据按顺序分为若干组(相邻在同一组),每组不满足所有条件,去掉最后一个条件后满足所有条件,求组数。
题解:
一种方法是每次倍增一组个数,对于组内跑bfs或者并查集,最后对组内不等关系判互恰,倍增结合二分。
正解O(n log n)。
相等关系具有传递性,可以用并查集在线维护。
不等关系不具有传递性,用平衡树维护每个点的不等关系。
对于相等关系,若在同一集合跳过,若在对方平衡树内则清空退出,否则合并双方集合。
合并使用启发式合并,就是大的并入小的,并修改对应不等关系平衡树处的表示。
对于不等关系,若在同一集合则清空退出,否则加入对方平衡树。
清空退出:用到的点加入栈,清空时只清栈内平衡树和栈内父亲,保证复杂度。(vis时间戳也可以优化常数)
记得开双倍数组。
#include<cstdio>
#include<cstring>
#include<set>
#include<stack>
#include<algorithm>
using namespace std;
const int maxn=; int ans,anss[maxn],pre,n,fa[maxn];
stack<int>s;
set<int>q[maxn];
set<int>::iterator it; void getans(int x){
anss[++ans]=x-pre;pre=x;
while(!s.empty()){
q[s.top()].clear();
fa[s.top()]=s.top();
s.pop();
}
}
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);} int main(){
scanf("%d",&n);
int u,v,w;
pre=;
for(int i=;i<=n;i++)fa[i]=i;//初始化
for(int i=;i<=n;i++){
scanf("%d%d%d",&u,&v,&w);
s.push(u);s.push(v);
u=find(u);v=find(v);
if(w==){
if(u==v)continue;
if(q[u].find(v)!=q[u].end())getans(i);
else{
if(q[u].size()>q[v].size())swap(u,v);
for(it=q[u].begin();it!=q[u].end();it++){
q[*it].erase(u);
q[*it].insert(v);
q[v].insert(*it);
}
fa[u]=v;
}
}else{
if(u==v)getans(i);
else{
q[u].insert(v);
q[v].insert(u);
}
}
}
printf("%d\n",ans);
for(int i=;i<=ans;i++)printf("%d\n",anss[i]);
return ;
}
另一种解法:如果只有一组,显然全局二分后找最长长度。
因为答案就有明显的递进性质,所以考虑使用倍增来扩展,失败后在使用区间二分,保证复杂度。
复杂度……是啥?代码未AC。
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
const int maxn=; int ans,anss[maxn],pre,n,fa[maxn];
int a[maxn],b[maxn],c[maxn];
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);} bool found(int l,int r){
bool ok=;
for(int i=l;i<=r;i++)if(c[i]&&find(a[i])!=find(b[i]))fa[fa[a[i]]]=fa[b[i]];
for(int i=l;i<=r;i++)if((!c[i])&&find(a[i])==find(b[i])){ok=;break;}
for(int i=l;i<=r;i++)fa[i]=i;
return ok;
}
int half(int x,int l,int r){
int mid;
while(l<r){
mid=(l+r)>>;
if(found(x,mid))l=mid+;
else r=mid;
}
return l;
}
int main(){
scanf("%d",&n);
int now=;
for(int i=;i<=n;i++)fa[i]=i;//初始化
for(int i=;i<=n;i++)scanf("%d%d%d",&a[i],&b[i],&c[i]);
while(now<=n){
int mx=;
while(now+(<<mx)<=n&&found(now,now+(<<mx)))mx++;
if(mx==){ans++;now++;anss[ans]=now;}
else{
now=half(now,now+(<<(mx-)),min(n,now+(<<mx)));
ans++;anss[ans]=now;
now++;
}
}
printf("%d\n",ans);
for(int i=;i<=ans;i++)printf("%d\n",anss[i]-anss[i-]);
return ;
}
Wrong Answer
★第三题
题意:给定n个点的树,m条路径(u到v)构成序列,q次询问序列L到R路径的交集。
题解:套路化地化树上询问为链上询问,处理一堆细节。
http://paste.ubuntu.com/25312404/
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <set> #define rep(i, l, r) for(int i=l; i<=r; i++)
#define dow(i, l, r) for(int i=l; i>=r; i--)
#define clr(x, c) memset(x, c, sizeof(x))
#define travel(x) for(edge *p=fir[x]; p; p=p->n)
#define all(x) (x).begin,(x).end
#define pb push_back
#define fi first
#define se second
#define l(x) Left[x]
#define r(x) Right[x]
#define lowbit(x) (x&-x) using namespace std; typedef long long ll;
typedef pair<int,int> Pii;
typedef long double ld;
typedef unsigned long long ull; inline int read()
{
int x=; bool f=; char ch=getchar();
while (ch<'' || ''<ch) f|=ch=='-', ch=getchar();
while (''<=ch && ch<='') x=x*+ch-'', ch=getchar();
return f?-x:x;
} #define maxn 500009
#define maxc 1000009 int n, m; struct edge{int y,z; edge *n;} e[maxn*], *fir[maxn], *pt=e;
void AddE(int x, int y, int z)
{
pt->y=y, pt->z=z, pt->n=fir[x], fir[x]=pt++;
pt->y=x, pt->z=z, pt->n=fir[y], fir[y]=pt++;
} int h[][maxn], dep[maxn]; ll d[maxn]; inline int lca(int a, int b)
{
if (dep[a]<dep[b]) swap(a,b);
for(int i=, tmp=dep[a]-dep[b]; tmp; tmp>>=,i++) if (tmp&) a=h[i][a];
if (a==b) return a;
dow(i,,) if (h[i][a] && h[i][a]!=h[i][b]) a=h[i][a], b=h[i][b];
return h[][a];
} int cn, rt, Left[maxc], Right[maxc]; Pii g[maxc];
inline Pii Union(Pii p0, Pii p1)
{
if (p0==Pii(,) || p1==Pii(,)) return Pii(,); int x1=p0.fi, y1=p0.se;
int x2=p1.fi, y2=p1.se, a, b, c, d;
if ((a=lca(x1,y1))==(b=lca(x2,y2)))
{
if (lca(x1,x2)==lca(x1,y1)) swap(x2,y2);
Pii tmp=Pii(lca(x1,x2),lca(y1,y2));
if (tmp.se==tmp.fi) return Pii(,); else return tmp;
}
else
{
if (dep[a]<dep[b]) swap(x1,x2), swap(y1,y2), swap(a,b);
c=lca(x1,x2), d=lca(y1,x2); if ((c==a) || (d==a)) return Pii(c,d);
c=lca(x1,y2), d=lca(y1,y2); if ((c==a) || (d==a)) return Pii(c,d);
else return Pii(,);
}
return Pii(,);
}
void Build(int l, int r, int &t)
{
t=++cn; if (l==r) {g[t]=Pii(read(),read()); return;}
int mid=(l+r)>>;
Build(l,mid,l(t)); Build(mid+,r,r(t));
g[t]=Union(g[l(t)],g[r(t)]);
} int L, R; Pii G;
void Que(int l, int r, int &t)
{
if (L<=l && r<=R)
{
if (G.fi==) G=g[t]; else G=Union(G,g[t]);
return;
}
int mid=(l+r)>>;
if (L<=mid) Que(l,mid,l(t));
if (mid<R) Que(mid+,r,r(t));
} int q[maxn], tot;
int main()
{
n=read();
rep(i, , n-) {int x=read(), y=read(), z=read(); AddE(x,y,z);}
q[tot=]=; while (tot)
{
int x=q[tot--];
for(int i=;h[i-][h[i-][x]];i++) h[i][x]=h[i-][h[i-][x]];
travel(x) if (p->y!=h[][x]) q[++tot]=p->y, h[][p->y]=x, d[p->y]=d[x]+p->z, dep[p->y]=dep[x]+;
}
Build(,m=read(),rt);
int Q=read(); while (Q--)
{
L=read(), R=read(); G=Pii(,);
Que(,m,rt);
printf("%I64d\n", d[G.fi]+d[G.se]-d[lca(G.fi,G.se)]*);
}
return ;
}
嗷嗷待补
第四题
第五题
题意:多组数据,给定年月日,求下一次同月同日为同星期几的年份。
题解:365%7=1,过一年星期加一天。
对于2.29前的日子,闰年在本年多+1。对于2.29后的日子,闰年在本年多+1。
对于2.29,四年四年跳特殊处理,还要处理跳到的年份是否闰年。
第六题
题意:给定一个n*m的01矩阵。
图像0的定义:存在1字符且1字符只能是由一个连通块组成,存在且仅存在一个由0字符组成的连通块完全被1所包围。
图像1的定义:存在1字符且1字符只能是由一个连通块组成,不存在任何0字符组成的连通块被1所完全包围。
连通的含义是,只要连续两个方块有公共边,就看做是连通。
完全包围的意思是,该连通块不与边界相接触。
题解:
要用巧妙的方法判断,否则会极其复杂。
在外圈加0后,从外圈到内圈消除,转化为:
图像0:一圈0连通块,一圈1联通块,一圈0联通块。
图像1:一圈0连通块,一圈1联通块。
注意每圈只能有1个联通块。
【比赛】百度之星2017 初赛Round A的更多相关文章
- 【比赛】百度之星2017 初赛Round B
第一题 题意:给定n*m网络,定义两个棋子在同行同列则相互攻击,同时要求两个棋子的行和列不能一小一大,求满足条件的最大摆放的方案数. 题解:ans=C(max(n,m),min(n,m)),就是在ma ...
- 百度之星2017初赛A-1005-今夕何夕
今夕何夕 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 百度之星2017初赛A轮 1001 小C的倍数问题
小C的倍数问题 Accepts: 1990 Submissions: 4931 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/3 ...
- 百度之星2017初赛A-1006-度度熊的01世界
度度熊的01世界 Accepts: 967 Submissions: 3064 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/3 ...
- 百度之星2017初赛A
雪崩,没晋级,补题 1001 分析:求n-1的约数个数 #include "iostream" #include "cstdio" #include " ...
- 百度之星2017初赛B1006 小小粉丝度度熊
思路: 考虑到补签卡一定是连续放置才更优,所以直接根据起始位置枚举.预先处理区间之间的gap的前缀和,在枚举过程中二分即可.复杂度O(nlog(n)). 实现: #include <iostre ...
- 【百度之星2014~初赛(第二轮)解题报告】Chess
声明 笔者近期意外的发现 笔者的个人站点http://tiankonguse.com/ 的非常多文章被其他站点转载.可是转载时未声明文章来源或參考自 http://tiankonguse.com/ 站 ...
- 【百度之星2014~初赛(第二轮)解题报告】JZP Set
声明 笔者近期意外的发现 笔者的个人站点http://tiankonguse.com/ 的非常多文章被其他站点转载,可是转载时未声明文章来源或參考自 http://tiankonguse.com/ 站 ...
- HDU - 6383 百度之星2018初赛B 1004 p1m2(二分答案)
p1m2 Accepts: 1003 Submissions: 4595 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072 ...
随机推荐
- linux的常用易忘命令
1.查看软件安装路径 [root@localhost ~]# which gcc /usr/bin/gcc 查询进程 ps -ef |grep redis 查看端口 netstat -lntp |g ...
- Memcached Hash算法
本文来自网易云社区 作者:吕宗胜 Hash算法 1. Memcached Hash介绍 我们在前面的文章中已经介绍过了Memcached的内存管理方式,LRU的策略.由于Memcached的数据存储方 ...
- Java 图像处理框架-Marvin
网上看到,摘录过来的,暂时还没涉足这方面的东西 Marvin 1.4.5 的插件接口支持处理多个图像作为输入,新的插件可通过多个图片来确认背景,新的插件可使用多个图片来合并相同场景. Marvin 是 ...
- 「日常训练」「小专题·USACO」 Ski Course Design (1-4)
题目 以后补 分析 mmp这题把我写蠢哭了 我原来的思路是什么呢? 每轮找min/max,然后两个决策:升min/降max 像这样子dfs找最优,然后花式剪枝 但是一想不对啊,这才1-4,哪有那么复杂 ...
- Windows模拟linux终端工具Cmder+Gow
1. 说明 Cmder:Windows下的终端模拟器. Gow: Windows下模拟Linux命令行工具集合.可以在windows执行linux下的大部分命令,如ls.grep.xargs等. 2. ...
- 【java并发编程实战】第五章:基础构建模块
1.同步容器类 它们是线程安全的 1.1 vector和hashtable. 和Collections.synchronizeXxx()一样.实现方式就是在每个方法里面加入synchronize代码块 ...
- Mysql性能优化一:SQL语句性能优化
这里总结了52条对sql的查询优化,下面详细来看看,希望能帮助到你 1, 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2,应尽量避免在 w ...
- 【Linux运维】LNMP环境配置
安装准备: Centos7.3 MYSQL5.6 PHP5.6 NGINX1.10.3 一.安装Mysql mysql:[root@host129 src]#cd /usr/local/src/ [r ...
- UnrealEngine4入门(二) 实现一个可用按键控制的球体
源码摘自官网guide,加上部分自己的理解和注释 接上篇博客 本文实现一个可用WASD控制滚动的球体 先创建一个可见的球体: 在CollidingPawn.cpp的构造函数ACollidingPawn ...
- 简明Python3教程 1.介绍
Python是少有的几种既强大又简单的编程语言.你将惊喜地发现通过使用Python即可轻松专注于解决问题而非和你所用的语言格式与结构. 下面是Python的官方介绍: Python is an eas ...