Link:

ARC065 传送门

C:

最好采取逆序贪心,否则要多考虑好几种情况

(从前往后贪心的话不能无脑选“dreamer”,"er"可能为"erase"/"eraser"的前缀)

#include <bits/stdc++.h>

using namespace std;
string s;
int main()
{
cin>>s;
for(int cur=s.size();cur;)
if(cur>=&&s.substr(cur-,)=="erase") cur-=;
else if(cur>=&&s.substr(cur-,)=="dream") cur-=;
else if(cur>=&&s.substr(cur-,)=="eraser") cur-=;
else if(cur>=&&s.substr(cur-,)=="dreamer") cur-=;
else return puts("NO"),;
puts("YES");
return ;
}

Problem C

注意:$strncpy$和$s.substr()$的第三个参数为长度

D:

题意:求与点$i$在图$G1$和图$G2$中的连通块序号均相同的点的个数

设1个点的序号对为$(a,b)$,其实就是求每对$(a,b)$的个数

然而我一开始沙茶得以为只能$O(n^2)$来统计……

明显用上$set$就只要$O(m*log(n))$了嘛,多维的统计都可以用$set$优化!

先跑两遍$dfs$求出每个点的$(a,b)$,再利用$set$优化$pair$的统计就好了

#include <bits/stdc++.h>

using namespace std;
typedef pair<int,int> P;
const int MAXN=2e5+;
map<P,int> mp;
struct edge{int nxt,to;}e[MAXN<<];
int c1[MAXN],c2[MAXN],sum1[MAXN],sum2[MAXN];
int n,k,l,x,y,head[MAXN],vis[MAXN],res[MAXN],tot,cnt; void add_edge(int from,int to)
{
e[++tot].nxt=head[from];e[tot].to=to;head[from]=tot;
e[++tot].nxt=head[to];e[tot].to=from;head[to]=tot;
} void dfs(int x,int c,int* col)
{
vis[x]=true;col[x]=c;
for(int i=head[x];i;i=e[i].nxt)
if(!vis[e[i].to]) dfs(e[i].to,c,col);
} void solve(int esum,int* col)
{
tot=cnt=;
memset(head,,sizeof(head));
memset(vis,false,sizeof(vis));
for(int i=;i<=esum;i++)
scanf("%d%d",&x,&y),add_edge(x,y);
for(int i=;i<=n;i++)
if(!vis[i]) dfs(i,++cnt,col);
} int main()
{
scanf("%d%d%d",&n,&k,&l);
memset(res,0x3f,sizeof(res));
solve(k,c1);solve(l,c2);
for(int i=;i<=n;i++)
sum1[c1[i]]++,sum2[c2[i]]++;
for(int i=;i<=n;i++)
mp[P(c1[i],c2[i])]++;
for(int i=;i<=n;i++)
printf("%d ",mp[P(c1[i],c2[i])]); return ;
}

Problem D

如果只求连通块最好使用并查集

提升效率并能减少代码量

E:

好像题目中专门提到曼哈顿/切比雪夫距离的任意一个往令一个想就对了……

设$a,b$两点间的初始距离为$d$,那么将所有距离为$d$的两点都连边,找到$a$所在的连通块即可

但曼哈顿距离涉及到了两个量,很难进行统一处理,因此要转换成切比雪夫距离

于是问题转化为将$max(|X_i-X_j|,|Y_i-Y_j|)=d$的$i,j$连边

明显可以排序后采取二分的方式,对于每个$X_i$,找到$X_j=X_i+d$中符合$Y_i-d\le Y_j\le Y_i+d$的点的个数,记为$cnt[i]$

接下来将$X_i$与$Y_i$交换后进行相同的操作,只不过要排除$|X_i-X_j|=|Y_i-Y_j|=d$的情况

最后$dfs$求出$a$所在连通块中$cnt$的总和$res=\sum cnt[i]$

要注意连边的细节:不能暴力连边,那样复杂度变为了$O(n^2)$

可以发现每次是向一个区间连边,且只要保证连通性不变,因此只要将区间连成一条链就行了!复杂度为$O(n)$

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int MAXN=1e5+;
struct edge{int nxt,to;}e[MAXN*];//一定要开8倍空间
struct data{int x,y,id;}dat[MAXN];
int n,d,a,b,x,y,head[MAXN],vis[MAXN],cnt[MAXN],tot=;
ll res=; void add_edge(int from,int to)
{
e[++tot].nxt=head[from];e[tot].to=to;head[from]=tot;
e[++tot].nxt=head[to];e[tot].to=from;head[to]=tot;
} bool operator < (data a,data b)
{
if(a.x!=b.x) return a.x<b.x;
return a.y<b.y;
} void solve(int k)
{
sort(dat+,dat+n+);
int cur,lst,l,r;
for(cur=lst=l=r=;cur<=n;cur++)
{
while((dat[l].x<dat[cur].x+d||dat[l].x==dat[cur].x+d&&dat[l].y<dat[cur].y-k)&&l<=n) l++;
while((dat[r].x<dat[cur].x+d||dat[r].x==dat[cur].x+d&&dat[r].y<=dat[cur].y+k)&&r<=n) r++;
if(l>n) break;
cnt[dat[cur].id]+=r-l;lst=max(lst,l);
if(lst>=r) continue; add_edge(dat[cur].id,dat[lst].id);
for(;lst<r-;lst++) add_edge(dat[lst].id,dat[lst+].id);
}
} void dfs(int x)
{
vis[x]=true;res+=cnt[x];
for(int i=head[x];i;i=e[i].nxt)
if(!vis[e[i].to]) dfs(e[i].to);
} int main()
{
scanf("%d%d%d",&n,&a,&b);
for(int i=;i<=n;i++)
scanf("%d%d",&x,&y),dat[i]={x+y,x-y,i}; d=max(abs(dat[a].x-dat[b].x),abs(dat[a].y-dat[b].y));
solve(d);
for(int i=;i<=n;i++) swap(dat[i].x,dat[i].y);
solve(d-); dfs(a);printf("%lld",res);
return ;
}

Problem E

Tip:此题边集数组要开8倍空间,但我觉得4倍就够了?跪求神犇们指点啊……

F:

对于每个点而言,其实只要关心其能翻转到的最右位置就好了,中间重复的翻转可以不管

于是可以先求出$lst[i]$表示第$i$位能翻转到的最右位置

令$dp[i][j]$为已经确定前$i-1$位,还有$j$个1可以自由支配时的方案数

常规地分第$i$位选$0/1$递推即可,$dp[n+1][0]$即为答案

#include <bits/stdc++.h>

using namespace std;
const int MAXN=,MOD=1e9+;
char s[MAXN];
int n,m,x,y,pre[MAXN],lst[MAXN],dp[MAXN][MAXN]; int main()
{
scanf("%d%d%s",&n,&m,s+);s[n+]='';
for(int i=;i<=n+;i++) //对第n+1项也要更新
pre[i]=(s[i]-'')+pre[i-],lst[i]=i;
for(int i=;i<=m;i++)
scanf("%d%d",&x,&y),lst[x]=max(lst[x],y);
for(int i=;i<=n+;i++) lst[i]=max(lst[i],lst[i-]); dp[][pre[lst[]]]=;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(dp[i][j])
{
int l=lst[i]+,r=lst[i+];
if(j) (dp[i+][pre[r]-pre[l-]+j-]+=dp[i][j])%=MOD;
if(lst[i]-(i-)-j) (dp[i+][pre[r]-pre[l-]+j]+=dp[i][j])%=MOD;
}
printf("%d",dp[n+][]);
return ;
}

Problem F

[Atcoder Regular Contest 065] Tutorial的更多相关文章

  1. [Atcoder Regular Contest 060] Tutorial

    Link: ARC060 传送门 C: 由于难以维护和更新平均数的值: $Average->Sum/Num$ 这样我们只要用$dp[i][j][sum]$维护前$i$个数中取$j$个,且和为$s ...

  2. [Atcoder Regular Contest 061] Tutorial

    Link: ARC061 传送门 C: 暴力$dfs$就好了 #include <bits/stdc++.h> using namespace std; typedef long long ...

  3. [Atcoder Regular Contest 064] Tutorial

    Link: ARC064 传送门 C: 贪心+对边界的特殊处理 #include <bits/stdc++.h> using namespace std; typedef long lon ...

  4. [Atcoder Regular Contest 063] Tutorial

    Link: ARC063 传送门 C: 将每种颜色的连续出现称为一段,寻找总段数即可 #include <bits/stdc++.h> using namespace std; ,len; ...

  5. [Atcoder Regular Contest 062] Tutorial

    Link: ARC 062 传送门 C: 每次判断增加a/b哪个合法即可 并不用判断两个都合法时哪个更优,因为此时两者答案必定相同 #include <bits/stdc++.h> usi ...

  6. AtCoder Regular Contest 061

    AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...

  7. AtCoder Regular Contest 094 (ARC094) CDE题解

    原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...

  8. AtCoder Regular Contest 092

    AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...

  9. AtCoder Regular Contest 093

    AtCoder Regular Contest 093 C - Traveling Plan 题意: 给定n个点,求出删去i号点时,按顺序从起点到一号点走到n号点最后回到起点所走的路程是多少. \(n ...

随机推荐

  1. Lua中调用C++方法

    目前项目,使用了Lua脚本,至于使用Lua的好处不再赘述了.于是对Tolua做了一些小小的学习,总结一下吧. 主要说一下如何在Lua中调用C++方法. Lua调用C++的桥梁,是tolua.tolua ...

  2. 2017ACM暑期多校联合训练 - Team 1 1001 HDU 6033 Add More Zero (数学)

    题目链接 Problem Description There is a youngster known for amateur propositions concerning several math ...

  3. HDU 2577 How to Type (字符串处理)

    题目链接 Problem Description Pirates have finished developing the typing software. He called Cathy to te ...

  4. 7.0docker镜像和仓库

    repository:镜像的仓库 registry :docker组件的仓库,docker镜像的存储服务 tag :镜像的标签 例:ubuntu:14.04  ubuntu:latest 删除镜像 d ...

  5. linux下暴力破解工具hydra【转】

    一.简介 Number one of the biggest security holes are passwords, as every password security study shows. ...

  6. 去掉每行的特定字符py脚本

    百度下载一个脚本的时候遇到那么一个情况.每行的开头多了一个空格.https://www.0dayhack.com/post-104.html 一个个删就不要说了,很烦.于是就有了下面这个脚本. #! ...

  7. 关于tcp连接对象在多进程中的错误:pickle.PicklingError

    如果需要在多进程中使用tcp连接的对象,那么不能再主进程中将这个对象创建好当做参数传给子进程,因为在创建子进程是需要序列化对象,然而socket对象是不能序列化的,会产生一个pickle.Pickli ...

  8. 安全测试===sqlmap(贰)转载

    十二.列举数据 这些参数用于列举出数据库管理系统信息.数据结构和数据内容. 1.一键列举全部数据 参数:--all 使用这一个参数就能列举所有可访问的数据.但不推荐使用,因为这会发送大量请求,把有用和 ...

  9. ASPxCheckBoxList控件获取selected项的text和value的方法

    设ASPxCheckBoxList的ClientInstanceName为list_ var needtext; for (var i = 0; i < list_.GetSelectedIte ...

  10. google fcm 推送的流程

    总结:1.给一个人推,能成功,2.给多个人推,有两种,一种是给组推,一种是给主题推,之前用的是组推,但是不成功,这里换成主题推: <?phpnamespace App\Http\Controll ...