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. 【比赛】STSRM 09

    第一题 题意:n个点,每个点坐标pi属性ai,从右往左将遇到的点向左ai范围内的点消除,后继续扫描. 现可以在扫描开始前提前消除从右往左任意点,问最少消除数(提前+扫描). n,pi,ai<=1 ...

  2. 小程序var that=this

    小程序的js函数中,一般第一句就是var that=this,那么此语句的必要性是什么呢?下面用一段代码来解释这个问题 Page({ //页面的初始数据 loadUsers: function () ...

  3. 八大疯狂的HTML5 Canvas及WebGL动画效果——8 CRAZY ANIMATIONS WITH WEBGL AND HTML5 CANVAS【收藏】

    HTML5, WebGL and Javascript have changed the way animation used to be. Past few years, we can only a ...

  4. poj 3104 Drying(二分查找)

    题目链接:http://poj.org/problem?id=3104 Drying Time Limit: 2000MS   Memory Limit: 65536K Total Submissio ...

  5. Java多态的实现原理

    1.多态的定义:指允许不同类的对象,对同一消息作出响应: 即同一消息可以根据发送对象的不同采用多种不同的行为方式: 2.多态的实现技术:动态绑定: 指在执行期间判断所引用对象的实际类型,根据其实际的类 ...

  6. Linking code for an enhanced application binary interface (ABI) with decode time instruction optimization

    A code sequence made up multiple instructions and specifying an offset from a base address is identi ...

  7. C 实现一个简易的Http服务器 (二)

    正文 - 直接搞起 C 实现一个简易的Http服务器 很久以前写过一个简易的http服务器, 后面和一个朋友交流, 反思后发现问题不少.在这里简单搞一下. 让其更加简单去表现httpd本质, 弱化协议 ...

  8. mui 怎样监听scroll事件的滚动距离

    var scroll = mui('.mui-scroll-wrapper').scroll(); document.querySelector('.mui-scroll-wrapper' ).add ...

  9. IE11中实现颜色渐变

    background: -ms-linear-gradient(left,#daa23e,#ad7f27); 下面是css3中颜色渐变对各个浏览器的写法:background: -webkit-lin ...

  10. pdf2htmlEX安装和配置

    1.下载 安装的依赖: sudo yum install cmake gcc gnu-getopt java-1.8.0-openjdk libpng-devel fontforge-devel ca ...