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. loj2540 「PKUWC 2018」随机算法

    pkusc 快到了--做点题涨涨 rp. 记 \(f(S,i)\) 表示 \(S\) 这个集合是决计不能选的(要么属于独立集,要么和独立集相连),或称已经考虑了的,\(i\) 表示此集合对应的最大独立 ...

  2. [hdu 3949]线性基+高斯消元

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3949 一开始给做出来的线性基wa了很久,最后加了一步高斯消元就过了. 之所以可以这样做,证明如下. 首 ...

  3. POJ1456:Supermarket(并查集+贪心)

    Supermarket Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 17634   Accepted: 7920 题目链接 ...

  4. C++开源库,欢迎补充。

    转载自:http://blog.csdn.net/kobejayandy/article/details/8681741 C++在"商业应用"方面,曾经是天下第一的开发语言,但这一 ...

  5. Gradle体验/第一篇:下装、安装、配置、体验

    http://jingyan.baidu.com/article/4d58d541167bc69dd4e9c009.html

  6. HDU1847 Good Luck in CET-4 Everybody!

    大学英语四级考试就要来临了,你是不是在紧张的复习?也许紧张得连短学期的ACM都没工夫练习了,反正我知道的Kiki和Cici都是如此.当然,作为在 考场浸润了十几载的当代大学生,Kiki和Cici更懂得 ...

  7. UVA 10668 Expanding Rods

    Problem A: Expanding Rods When a thin rod of length L is heated n degrees, it expands to a new lengt ...

  8. locust===官方说明文档,关于tasks

    安装: >>> pip  install locust locust在官方simple_code中如下: from locust import HttpLocust, TaskSet ...

  9. python读取doc

    import os, time, fnmatch from docx import Document class search: def __init__(self, path, search_str ...

  10. Mac-安装itellij idea

    1.安装解压 Unzip and copy JetbrainsCrack.jar to /Applications/CLion.app/Contents/bin/JetbrainsCrack.jar ...