bzoj 4377: [POI2015]Kurs szybkiego czytania 数学

11 篇文章 0 订阅

       令f(i)=ai+b,由题意(a,n)==1,那么可以得到f(i)两两不同。同时可以发现对于一个f(i),如果f(i)已经确定,那么i~i+m-1的01串也就确定了,因此我们可以判断f(i)为开头时是否与给定串相同。

       然后按照给定的串的每一位,得到f(i)不可能出现的位置;另外f(n-m+1)~f(n-1)也是不可能的。那么把所有不可能的求并,然后补集的大小就是答案。

AC代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int n,a,b,p,m,cnt; struct node{ int x,y; }c[4000005];
void add(int x,int y){
	if (x<=y){ c[++cnt].x=x; c[cnt].y=y; } else{
		c[++cnt].x=x; c[cnt].y=n-1;
		c[++cnt].x=0; c[cnt].y=y;
	}
}
bool cmp(node x,node y){ return x.x<y.x; }
int main(){
	scanf("%d%d%d%d%d",&n,&a,&b,&p,&m);
	int i,now=0; char ch=getchar();
	while (ch<'0' || ch>'9') ch=getchar();
	for (i=1; i<=m; i++,ch=getchar(),now=(now+a)%n){
		if (ch=='0') add((p-now+n)%n,(n-1-now+n)%n); else
			add((n-now)%n,(p-1-now+n)%n);
	}
	for (i=1,b=(b-a+n)%n; i<m; i++,b=(b-a+n)%n) add(b,b);
	sort(c+1,c+cnt+1,cmp);
	int tail=-1,ans=0;
	for (i=1; i<=cnt; i++)
		if (c[i].x>tail){ ans+=c[i].x-tail-1; tail=c[i].y; }
		else tail=max(tail,c[i].y);
	printf("%d\n",ans+n-1-tail);
	return 0;
}


by lych

2016.3.28

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值