codeforces B. Binary Period

题意:
给出一个只由 0和1 构成的子串 t ,要你求出一个原串,并且原串长度不大于两倍子串长度,同时原串的循环节最短。
思路:
仔细想想不难发现,当字串都是0或都是1的时候,原串只需要和字串一样即可;当字串既包含0又包含1的时候,原串只有两种可能,101010…或者是010101…。
为什么这么说呢?因为原串的长度可以是字串的二倍,那我只需要在字串的每一位旁边补上和它不同的数字即可。比如说1110,我在第一位数字后面补0,第二位数字后面补0,第三位后面补0,第四位前面补1,这样就是10101010,保证了是字串的同时也保证了循环节最短。

代码:

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+10;
long long int s[N];
vector<long long int> pre;
int main()
{
	int t;
	cin >> t;
	while(t--)
	{
		int a , b, q;
		cin >> a >> b >> q;
		for(int i = 0 ; i < q ; i++)
		{
			long long int l  , r;
			long long int res = 0;
			cin >> l >> r;
			long long int z1;
			long long int sd = a*b;
			z1 = l/sd*sd;
			if(z1 < l)
			{
				z1 = z1+sd;
			}
			long long int z2;
			z2 = z1+sd;
			for(long long int j = z1 ; j < z2 ; j++)
			{
				if((j%a)%b!=(j%b)%a)
				   res++;
			}
			//cout << res << endl;
			z2 = r/sd*sd;
			long long int k = (z2/sd-z1/sd)*res;
			if(k<0)
			  k = 0;
			//cout << k << endl;
			for(long long int j = l ; j < z1 ; j++)
			{
				if((j%a)%b!=(j%b)%a)
				   k++;
			}
			for(long long int j = z2 ; j <= r ; j++)
			{
				if((j%a)%b!=(j%b)%a)
				   k++;
			}
			s[i] = k;
		}
		for(int i = 0 ; i < q-1 ; i++)
		{
			cout << s[i] << ' ';
		}
		cout << s[q-1] << endl;
	}
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值