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. 我用JAVA做了个简易图像相似度计算器

    简单说两句: 笔主利用这个七夕前后两天的寂寞时光,用JAVA磨了一个简单的图像相似度计算小程序,就在刚才终于纠结完毕,输出了1.0版本,小小的满足了一下可怜的虚荣心..→_→ 使用最简单最基础的感知哈 ...

  2. AWS CLI command example

    1.list ec2 instance-id, instance status, type, ip address, name aws ec2 describe-instances --query ' ...

  3. maven2应用之jar插件使用介绍

    [转载声明] 转载时必须标注:本文来源于铁木箱子的博客http://www.mzone.cc [本文地址] 本文永久地址是:http://www.mzone.cc/article/236.html 有 ...

  4. 【Foreign】字符串匹配 [KMP]

    字符串匹配 Time Limit: 10 Sec  Memory Limit: 256 MB Description Input Output Sample Input 3 3 6 3 1 2 1 2 ...

  5. [BZOJ1391]解题报告|网络流的又一类建图&Dinic的若干优化

    1391: [Ceoi2008]order 有N个工作,M种机器,每种机器你可以租或者买过来. 每个工作包括若干道工序,每道工序需要某种机器来完成,你可以通过购买或租用机器来完成. 现在给出这些参数, ...

  6. cdp协议通信并发编程基础之进程

    一 . 基于UDP的套接字 udp是无链接的所以先启动哪一段都不会报错 udp服务端 import socket server=socket.socket(socket.AF_INET,socket. ...

  7. linux环境下的GUN make学习笔记(一)

    第一章:概述 1.1:make概述 在linux环境下使用make工具能够比较容易的构建一个属于自己的工程,整个工程的编译只需要一个命令就可以完成编译.连接以至于最后的执行.不过我们需要投入一些时间去 ...

  8. zabbix mysql自动发现规则

    1.配置mysql,添加监控用的账号,授予查看所有用户线程/连接的权限 GRANT PROCESS ON *.* TO 'zabbix'@'127.0.0.1' identified BY '20c1 ...

  9. 同源、同源策略、跨域问题、django解决方案

    什么是同源: URL由协议.域名.端口和路径组成,如果两个URL的协议.域名和端口相同,则表示他们同源. 注意:假如你的网站ip是123.123.123.123,网站的域名是www.abc.com. ...

  10. KVM(八)使用 libvirt 迁移 QEMU/KVM 虚机和 Nova 虚机

    1. QEMU/KVM 迁移的概念 迁移(migration)包括系统整体的迁移和某个工作负载的迁移.系统整理迁移,是将系统上所有软件包括操作系统完全复制到另一个物理机硬件机器上.虚拟化环境中的迁移, ...