Link:

ARC060 传送门

C:

由于难以维护和更新平均数的值:

$Average->Sum/Num$

这样我们只要用$dp[i][j][sum]$维护前$i$个数中取$j$个,且和为$sum$的个数

最后统计$dp[n][k][k*a]$即可

这样就得到了$O(n^4)$的解法

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int MAXN=;
int n,a,sum,dat[MAXN];
ll dp[MAXN][MAXN][MAXN*MAXN],res=; int main()
{
scanf("%d%d",&n,&a);
for(int i=;i<=n;i++) scanf("%d",&dat[i]); dp[][][dat[]]=;sum=dat[]+dat[];
for(int i=;i<=n;i++) dp[i][][]=;
for(int i=;i<=n;i++,sum+=dat[i])
for(int j=;j<=i;j++)
for(int k=;k<=sum;k++)
{
dp[i][j][k]=dp[i-][j][k];
if(k>=dat[i]) dp[i][j][k]+=dp[i-][j-][k-dat[i]];
} for(int i=;i<=n;i++) res+=dp[n][i][i*a];
printf("%lld",res);
return ;
}

O(n^4)

不过真的需要同时记录个数与和吗?

如果将$dat[i]->a-dat[i]$,只要维护最终和为0的情况即可

于是将复杂度降到了$O(n^3)$

#include <bits/stdc++.h>

using namespace std;
const int MAXN=,ZERO=;
typedef long long ll;
int n,a,x,cur;
ll dp[][*ZERO]; int main()
{
scanf("%d%d",&n,&a);
dp[cur^][ZERO]=;
for (int i=;i<=n;i++,cur^=)
{
scanf("%d",&x);x-=a;
for (int j=MAXN;j+MAXN<*ZERO;j++)
dp[cur][j]=dp[cur^][j]+dp[cur^][j-x];
}
printf ("%lld\n",dp[cur^][ZERO]-);
}

O(n^3)

D:

遇到多次取模问题时,有以下对数据的典型分类:

1、$base\le sqrt(n)$,此时直接枚举即可

2、$base>sqrt(n)$,此时由$n=p*base+q$和$p+q=s$可得$n-s=p(base-1)$

从小到大枚举$n-s$的所有约数算出$base$再验证

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
ll n,s,sq; bool check(ll b)
{
ll ret=,t=n;
for(;t;t/=b) ret+=t%b;
return (ret==s);
} ll solve()
{
if(s==n) return n+; //s=1时不特殊处理
if(s>n) return -; for(int i=;i<=sq;i++)
if(check(i)) return i;
for(int i=sq;i;i--) //注意枚举顺序
if((n-s)%i==&&check((n-s)/i+)) return ((n-s)/i+);
return -;
} int main()
{
scanf("%lld%lld",&n,&s);sq=sqrt(n);
printf("%lld",solve());
return ;
}

Problem D

很多题目都是暴力枚举$k\le sqrt(n)$,对$k>sqrt(n)$进行分块等处理来保证$O(nlog(n))$的复杂度

E:

比较明显的序列上倍增裸题

记录每个点能达到的最大距离再倍增即可

可以用假设法证明$dist(i,j)=dist(j,i)$

#include <bits/stdc++.h>

using namespace std;
const int MAXN=1e5+;
int n,l,q,a,b,dat[MAXN],nxt[MAXN][]; int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&dat[i]);
scanf("%d",&l);
for(int i=;i<=n;i++)
nxt[i][]=upper_bound(dat+,dat+n+,dat[i]+l)-dat-; for(int i=n;i;i--)
for(int j=;j<=;j++)
nxt[i][j]=nxt[nxt[i][j-]][j-]; scanf("%d",&q);
while(q--)
{
scanf("%d%d",&a,&b);
if(a>b) swap(a,b); int res=;
for(int i=;i>=;i--)
if(nxt[a][i]&&nxt[a][i]<b) a=nxt[a][i],res+=(<<i);
printf("%d\n",res+);
}
return ;
}

Problem E

F:

首先要在对小数据尝试后得到结论:

分成的组数只可能为$1 / 2 / len(s)(当每个字符都相同时)$

接下来只要判断任意一个$s$的前缀/后缀是否有循环节即可

%陈主力的代码后找到了最简易的判断方式:$KMP$算法中的$nxt$数组!

由画图可知:一个字符串最长相同的前/后缀有重叠部分且剩余部分为$len$的约数则其有循环节

因此$pos\% (pos-nxt[pos])==0$时则$pos$为有循环节的前缀/后缀

正反求一次$nxt$数组枚举每一个分割点判断就好啦

#include <bits/stdc++.h>

using namespace std;
const int MAXN=5e5+;
char s[MAXN];
int len,res=,nxt1[MAXN],nxt2[MAXN]; void cal_nxt(int* nxt)
{
int k=;
for(int i=;i<=len;i++)
{
while(k&&s[k+]!=s[i]) k=nxt[k];
if(s[k+]==s[i]) k++;nxt[i]=k;
}
} bool check(int* nxt,int pos)
{
if(!nxt[pos]) return false;
return (pos%(pos-nxt[pos])==);
} int main()
{
scanf("%s",s+);len=strlen(s+);
cal_nxt(nxt1);
if(!check(nxt1,len)) printf("1\n1");
else if(nxt1[len]==len-) printf("%d\n1",len);
else
{
reverse(s+,s+len+);
cal_nxt(nxt2);
for(int i=;i<=len;i++)
res+=(!check(nxt1,i))&(!check(nxt2,len-i));
printf("2\n%d",res);
}
return ;
}

Problem F

Review:

感觉$Atcoder$里的题目对推断能力要求比较高

还是要多尝试小数据,大胆猜结论再证明

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

  1. [Atcoder Regular Contest 061] Tutorial

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

  2. [Atcoder Regular Contest 065] Tutorial

    Link: ARC065 传送门 C: 最好采取逆序贪心,否则要多考虑好几种情况 (从前往后贪心的话不能无脑选“dreamer”,"er"可能为"erase"/ ...

  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 060 F题第一问答案证明

    一切的开始 令 \(x\) 为字符串,\(p\) 为正整数.如果对于满足 \(0\le i<|x|−p\) 的任何整数 \(i\) 满足 \(x[i]=x[i+p]\),则 \(p\) 称为 \ ...

  7. AtCoder Regular Contest 060

    C - 高橋君とカード / Tak and Cards 思路:dp,先说说我想的,我写的dp数组是dp[i][j][k],表示从前i个数字中,选择j个数字,平均值为k,则dp[i][j][k] = d ...

  8. AtCoder Regular Contest 061

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

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

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

随机推荐

  1. saltshaker填坑

    参考资料: https://github.com/yueyongyue/saltshaker http://blog.sina.com.cn/s/blog_b21312340102whzw.html ...

  2. Ubuntu下kafka集群环境搭建及测试

    kafka介绍: Kafka[1是一种高吞吐量[2]  的分布式发布订阅消息系统,有如下特性: 通过O(1)的磁盘数据结构提供消息的持久化,这种结构对于即使数以TB的消息存储也能够保持长时间的稳定性能 ...

  3. 【BZOJ】ARC083 E - Bichrome Tree

    [算法]树型DP [题意]给定含n个点的树的形态,和n个数字Xv,要求给每个点赋予黑色或白色和权值,满足对于每个点v,子树v中和v同色的点的权值和等于Xv.n<=10^5 [题解]首先每个点的权 ...

  4. sort函数_C++

    C++的STL库里有一个 sort 函数,它就是随机化快速排序,速度比快速排序还快,因为它克服了逆序时被卡成O(n2)的情况 想要使用 sort 首先要在头文件里申明 #include<algo ...

  5. Node.js 编码转换

    Node.js自带的toString()方法不支持gbk,因此中文转换的时候需要加载第三方库,推荐以下两个编码转换库,iconv-lite和encoding.       iconv, iconv-l ...

  6. Java相关框架

    框架 类型 设计(个人理解) HK2 自动注入框架 Jersey RESTful Jetty HTTP服务 Retrofit HTTP客户端 ActiveMQ 消息组件 主题.队列 Redis K-V ...

  7. USB接口无法识别设备

    http://windows.microsoft.com/zh-cn/windows/answers?tId=14fa1e44-0a19-48ef-9ba7-b7e512a837a4 小琼子 提问 2 ...

  8. Windows 的GUID

    GUID(全称:Globally Unique Identifier),是一种由算法生成的二进制长度为128位的数字标识符.GUID主要用于在拥有多个节点.多台计算机的网络或系统中.在理想情况下,任何 ...

  9. Google开源命令行参数解析库gflags

    Google开源命令行参数解析库gflags http://blog.csdn.net/lming_08/article/details/25072899 CMDLINE的解析 http://blog ...

  10. springboot整合mybatis+pageHelper

    springboot整合mybatis+pageHelper 〇.搭建sporingboot环境,已经整合mybatis环境,本篇主要是添加pageHelper工具 一.添加依赖 <!-- 分页 ...