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. 使用 URLDecoder 和 URLEncoder 对中文字符进行编码和解码

    原文: https://blog.csdn.net/justloveyou_/article/details/57156039 使用 URLDecoder 和 URLEncoder 对中文字符进行编码 ...

  2. SICAU-OJ: 三角关系

    三角关系 题意: 给出两个数n和k,统计(a,b,c)三元组满足(a+b)%k=0,(b+c)%k=0,(a+c)%k=0且1<=a,b,c<=n的数量. 题解: 由(a+b)%k=0,( ...

  3. kafka.common.ConsumerRebalanceFailedException异常解决

    kafka.common.ConsumerRebalanceFailedException: group_dd-1446432618163-2746a209 can't rebalance after ...

  4. eclipse 主题文件配置

    eclipse市场搜索 Eclipse Color Theme ----用于控制文本域主题 Eclipse 4 Chrome Theme  chrome风格的主题 最新的:Jeeeyul's Them ...

  5. 前端面试:区分XSS和CSRF

    xss:跨站点攻击.xss攻击的主要目的是想办法获取目标攻击网站的cookie,因为有了cookie相当于有了session,有了这些信息就可以在任意能接进互联网的PC登陆该网站,并以其他人的身份登陆 ...

  6. Python基础(8)迭代器、生成器

    一 什么是迭代 1 重复 2 下一次重复是基于上一次的结果 # while True: # cmd=input('>>: ') # print(cmd) # l=['a','b','c', ...

  7. 访问localhost与127.0.0.1的区别

    很多人会接触到这个ip地址127.0.0.1.也许你会问127.0.0.1是什么地址?其实127.0.0.1是一个回送地址,指本地机,一般用来测试使用.大家常用来ping 127.0.0.1来看本地i ...

  8. 【洛谷 P1666】 前缀单词 (Trie)

    题目链接 考试时暴搜50分...其实看到"单词","前缀"这种字眼时就要想到\(Trie\)的,哎,我太蒻了. 以一个虚点为根,建一棵\(Trie\),然后\( ...

  9. shell脚本(傻瓜式处理文件到指定分类)

    前言 每一到两周,我大概会新增十多个甚至更多的资料文件,都是些最近遇到的一些问题的总结或者相关技术文档,但是资料都是在公司电脑上,拷贝到自己电脑上后,又得一个个去找一个这个应该放到哪个分类,个人感觉很 ...

  10. UVA 10303 How Many Trees? (catlan)

    刚开始没看出时卡特兰数列.直接套高精度版 #include <map> #include <set> #include <list> #include <cm ...