[Atcoder Regular Contest 060] Tutorial
Link:
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的更多相关文章
- [Atcoder Regular Contest 061] Tutorial
Link: ARC061 传送门 C: 暴力$dfs$就好了 #include <bits/stdc++.h> using namespace std; typedef long long ...
- [Atcoder Regular Contest 065] Tutorial
Link: ARC065 传送门 C: 最好采取逆序贪心,否则要多考虑好几种情况 (从前往后贪心的话不能无脑选“dreamer”,"er"可能为"erase"/ ...
- [Atcoder Regular Contest 064] Tutorial
Link: ARC064 传送门 C: 贪心+对边界的特殊处理 #include <bits/stdc++.h> using namespace std; typedef long lon ...
- [Atcoder Regular Contest 063] Tutorial
Link: ARC063 传送门 C: 将每种颜色的连续出现称为一段,寻找总段数即可 #include <bits/stdc++.h> using namespace std; ,len; ...
- [Atcoder Regular Contest 062] Tutorial
Link: ARC 062 传送门 C: 每次判断增加a/b哪个合法即可 并不用判断两个都合法时哪个更优,因为此时两者答案必定相同 #include <bits/stdc++.h> usi ...
- Atcoder Regular Contest 060 F题第一问答案证明
一切的开始 令 \(x\) 为字符串,\(p\) 为正整数.如果对于满足 \(0\le i<|x|−p\) 的任何整数 \(i\) 满足 \(x[i]=x[i+p]\),则 \(p\) 称为 \ ...
- AtCoder Regular Contest 060
C - 高橋君とカード / Tak and Cards 思路:dp,先说说我想的,我写的dp数组是dp[i][j][k],表示从前i个数字中,选择j个数字,平均值为k,则dp[i][j][k] = d ...
- AtCoder Regular Contest 061
AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...
- AtCoder Regular Contest 094 (ARC094) CDE题解
原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...
随机推荐
- 【BZOJ 3123】 [Sdoi2013]森林 主席树启发式合并
我们直接按父子关系建主席树,然后记录倍增方便以后求LCA,同时用并查集维护根节点,而且还要记录根节点对应的size,用来对其启发式合并,然后每当我们合并的时候我们都要暴力拆小的一部分重复以上部分,总时 ...
- WordPress后台edit-tags.php里无限栏目分类实现
在 WordPress 里 http://localhost/wordpress3.6.1/wp-admin/edit-tags.php?taxonomy=category 这个链接可以显示 WP 里 ...
- 怎么将数据库从Oracle迁移到SQL Server,或从Oracle迁移到MySQL
有时候我们有迁移数据库的需求,例如从Oracle迁移到SQL Server,或者从MySQL迁移到Oracle. 很多江湖好汉一时不知如何手工操作,所幸的是Navicat提供了迁移的自动化操作界面. ...
- Codeforces Round #532 (Div. 2) 题解
Codeforces Round #532 (Div. 2) 题目总链接:https://codeforces.com/contest/1100 A. Roman and Browser 题意: 给出 ...
- photo@PKU
- 固定width但是有间隔
<!DOCTYPE > <html> <head> <title></title> <meta name="name&quo ...
- hibernate连接oracle数据库
前言:以下所有的操作都是基于你已经成功安装了oracle数据库并且java的开发环境正常的情况下进行的. 如果没有完善请先配置基础环境. 第一步:配置需要的环境(下载并导入需要的包). 下载链接:ht ...
- TDS开启log TDS开启SSL
参考: http://www.ibm.com/developerworks/tivoli/library/t-tds-perf/ 1. 编辑ldif文件如下 dn: cn=Audit, cn=Log ...
- 河南省第十届省赛 Plumbing the depth of lake (模拟)
title: Plumbing the depth of lake 河南省第十届省赛 题目描述: There is a mysterious lake in the north of Tibet. A ...
- phoronix-test-suite测试云服务器
centos系统 phoronix-test-suite是目前Linux下比较常用的性能测试软件. 使用phoronix-test-suite条件前提:需要安装php5,需要PHP都DOM扩展 因为是 ...