test20180922 古代龙人的谜题
题意
问题描述
Mark Douglas是一名调查员。他接受了「调查古代龙人」的任务。经过千辛万苦,Mark终于找到了一位古代龙人。Mark找到他时,他正在摆弄一些秘药,其中一些药丸由于是从很久以前流传下来的,发出了独特的光泽。古代龙人告诉了Mark一些他想知道的事情,看了看手中的秘药,决定考一考这位来访者。
古代龙人手中共有n粒秘药,我们可以用1表示「古老的秘药」,其余的用0表示。他将它们排成一列。古代龙人认为平衡是美的,于是他问Mark能选出多少个「平衡的区间」。「平衡的区间」是指首先选出一个区间[L, R],在它内部选出一个中间点mid,满足L<mid<R,mid是「古老的秘药」,且区间[L, mid]和[mid, R]中「古老的秘药」个数相等。
输入格式
输入文件名为puzzle.in。
第一行为一个正整数idx表示该测试点所属的子任务编号,子任务的详细信息请见「数据范围」。样例的子任务编号为0。
第二行为一个正整数n。
第三行为一个长度为n的字符串,仅包含0和1。
输出格式
输出文件名为puzzle.out。
输出仅一行表示答案。
样例输入
0
7
1101011
样例输出
7
数据范围
本题采用捆绑测试,只有通过一个子任务中的全部测试点才能拿到这个子任务的分数。
对于所有子任务:1≤n≤〖10〗^6。各子任务分值及特殊约束如下:
子任务1(8%):1≤n≤50。
子任务2(26%):1≤n≤300。
子任务3(24%):1≤n≤2000。
子任务4(5%):n≥3,字符串中仅有3个1。
子任务5(12%):字符串中全是1。
子任务6(25%)。
分析
考场做法
考虑分别计算以i为结尾,起始在[1,i-1]内的合法区间个数。
按串的0/1分为两种情况。
- 此位是0。先算前面0的贡献,考虑维护一个cnt[2]数组,令每遇到一个1就让cur异或1,统计0的个数,相当于按1划分0的段,显然此位的答案应加上cnt[cur^1]。然后算1的贡献,应该是此位之前1的中,距它中间间隔了正偶数个1的1的个数。
- 此位是1。先算前面0的贡献,应该是与此1同段的,且是非相邻0段的0的个数。所以要维护一个last数组,代表此位之前最近的1的位置。然后算1的贡献,应该是此位之前的1中,距它中间间隔了正奇数个1的1的个数。
代码
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<complex>
#pragma GCC optimize ("O0")
using namespace std;
template<class T> inline T read(T&x)
{
T data=0;
int w=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
w=-1;
ch=getchar();
}
while(isdigit(ch))
data=10*data+ch-'0',ch=getchar();
return x=data*w;
}
typedef long long ll;
const int INF=0x7fffffff;
const int MAXN=1e6+7;
int n;
char s[MAXN];
int last[MAXN];
int pre[MAXN];
int cnt[2],cur=0;
int f[MAXN];
/*
0
5
10010
*/
int main()
{
freopen("puzzle.in","r",stdin);
freopen("puzzle.out","w",stdout);
int id;
read(id);
read(n);
scanf("%s",s+1);
ll ans=0;
for(int i=1;i<=n;++i)
{
pre[i]=pre[i-1]+(s[i]=='1');
if(s[i]=='0')
{
f[i]=cnt[cur^1]+(pre[i]-1)/2;
++cnt[cur];
last[i+1]=last[i];
}
else if(s[i]=='1')
{
f[i]=pre[i-1]/2+cnt[cur]-(i-last[i]-1);
// cerr<<" cnt="<<cnt[cur]<<" judge="<<judge(i)<<endl;
cur^=1;
last[i+1]=i;
}
// cerr<<i<<" f="<<f[i]<<endl;
// cerr<<" cur="<<cur<<" cnt="<<cnt[cur]<<endl;
ans+=f[i];
}
printf("%lld\n",ans);
// fclose(stdin);
// fclose(stdout);
return 0;
}
题解
由于当我们确定了区间的两个端点以后,合法的中间点最多只有一个,且只要中间点存在(即区间[L, R]内有奇数个1)该区间就合法,所以我们枚举左端点L,同时维护在L右边且区间[1, R]内1的个数为奇数/偶数的点R的个数,答案就可以统计出来了。
std
#include <cstdio>
using LL = long long;
const int MAXN = 1e6 + 5;
int n, seq[MAXN];
int cnt, right[MAXN];
LL sum[2];
int main() {
#ifndef LOCAL
freopen("puzzle.in", "r", stdin);
freopen("puzzle.out", "w", stdout);
#endif
scanf("%*d%d", &n); cnt = 0;
for (int i = 1; i <= n; ++i) {
scanf("%1d", seq + i);
cnt += seq[i];
}
int tmp = 0;
for (int i = n, j = cnt; i; --i) {
++tmp;
if (seq[i] == 1) {
right[j--] = tmp; tmp = 0;
}
}
sum[0] = sum[1] = 0;
for (int i = 1; i <= cnt; i += 2) sum[1] += right[i];
for (int i = 2; i <= cnt; i += 2) sum[0] += right[i];
LL ans = 0;
tmp = 0;
for (int i = 1, j = 1; i <= n; ++i) {
++tmp;
if (seq[i] == 1) {
ans += (tmp - 1ll) * (right[j] - 1ll) + tmp * (sum[j & 1] - right[j]);
sum[j & 1] -= right[j];
++j; tmp = 0;
}
}
printf("%lld\n", ans);
return 0;
}
test20180922 古代龙人的谜题的更多相关文章
- NOIp2018集训test-9-22(am/pm) (联考三day1/day2)
szzq学长出的题,先orz一下. day1 倾斜的线 做过差不多的题,写在我自己的博客里,我却忘得一干二净,反而李巨记得清清楚楚我写了的. 题目就是要最小化这个东西 $|\frac{y_i-y_j} ...
- SQL 谜题(硬币的组合)
问题:早在ITPUB中看过有个SQL高手,喜欢出谜题,以下是一个谜题.我试用SQL SERVER解决此问题. 用1分,5分,10分,25分,50分硬币凑成一元,总共有几种组合办法? SELECT'1* ...
- [变]C#谜题(1-10)表达式篇
[变]C#谜题(1-10)表达式篇 最近偶然发现了<Java谜题>,很有意思,于是转到C#上研究一下. 本篇是关于表达式的一些内容. 谜题1:奇数性(负数的取模运算) 下面的方法意图确定它 ...
- BZOJ1951[SDOI2010]古代猪文
Description "在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心--" --选自猪王国民歌 很久 ...
- UOJ260 【NOIP2016】玩具谜题
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...
- 【BZOJ1951】【SDOI2010】古代猪文 Lucas定理、中国剩余定理、exgcd、费马小定理
Description “在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心……” ——选自猪王国民歌 很久很久以前,在山的那边 ...
- 发布HTML5 RTS游戏-古代战争
古代战争 游戏介绍 "古代战争"是一个2.5D即时战略游戏,使用了帝国时代2的素材,并参考了它的游戏设计和玩法. 游戏基于YEngine2D引擎开发,具备生产.建造.资源采集.战斗 ...
- BZOJ-1951 古代猪文 (组合数取模Lucas+中国剩余定理+拓展欧几里得+快速幂)
数论神题了吧算是 1951: [Sdoi2010]古代猪文 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 1573 Solved: 650 [Submit ...
- 几个Unicode新知识:扩展ANSI有很多种(256个字符),Unicode表示ANSI字符时高字节为0,Unicode不包括古代字符
都是有些模糊的概念,特别是Unicode不包括古代字符让我有点惊讶.看来Unicode只适用于大多数情况,一旦有无法表示的字符,那该怎么办呢? ANSI针对英语设计的,当处理带有音调标号(形如汉语的拼 ...
随机推荐
- h1042 N!大数乘int
计算10000以内某个数的阶乘,即大数乘以int,考虑到一个int存一个数位过于繁琐且浪费空间,采用万进制 一个int存四个位数,但注意除了最高位,其他位不够四位数时要加上前导0凑够四位: 例1234 ...
- Hibernate---运行原理
Hibernate---运行原理
- OC 类对象和类加载
//------------------------Persion类----------------------------// 1 #import "Person.h" @imp ...
- 小程序中的bindtap和catchtap的区别(交流QQ群:604788754)
bindtap绑定的节点,如果他的父节点也有绑定事件,点击之后就会出现冒泡. catchtap绑定的节点,如果他的父节点也有绑定事件,点击之后不会出现冒泡.
- jsp jsp运行原理
JSP的运行原理 每个jsp页面在第一次被访问时,WEB容器都会把请求交给jsp引擎(一个java程序).Jsp 引擎先将jsp翻译成一个_jspServlet实质上也是一个servlet,然后按照 ...
- httpclient 多线程请求
线程请求执行 当配备一个线程池管理器后,如PollingClientConnectionManager,HttpClient就能使用执行着的多线程去执行并行的多请求. PollingClientCon ...
- hadoop kafka install (6)
reference: http://kafka.apache.org/quickstart http://dblab.xmu.edu.cn/blog/1096-2/ hadoop@iZuf68496 ...
- Hibernate基于【XML】和【注解】——完整实例
Eclipse中新建Java Project工程: 工程结构 和 需要的Jar包: 我用的SqlServer数据库,所以连接数据库的Jar包是sqljdbc4.jar 一.基于XML配置 1.实体 ...
- Apache自带性能测试工具ab的使用
Apache服务器套件自带ab,只要安装Apache即可,无需另行安装ab.ab位于%ApacheHome%/bin目录下(“%ApacheHome%”为Aapche安装路径),你也可以把ab.exe ...
- Java——IO类,字节流读数据
body, table{font-family: 微软雅黑} table{border-collapse: collapse; border: solid gray; border-width: 2p ...