ICPC2019徐州区域赛复现赛

C < 3 numbers

教训就是不能看见素数就不管三七二十一直接上线性筛板子,还是需要多仔细想想题意。

题解:
解法一
这是一道素数密度的题目,首先需要推出一个结论。一个常识就是素数越往后是越来越分散的。观察素数表以后可以发现从100左右开始,如果区间长度超过了50(估计值),那么区间内的素数一定小于1/3.。如果区间的长度小于50,那么对于这个区间内的所有数做一遍√n的素数判断就可以。

代码:

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl '\n'
using namespace std;


int b[25] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};
const int N = 1e5 + 100;

bool prime(int x)
{
	for(int i = 0; i < 25; i ++)
	{
		if(x % b[i] == 0 && x != b[i])
			return 0;
	}
	return 1;
}

int main()
{
	int t;
	scanf("%d", &t);
	while(t --)
	{
		int l, r;
		scanf("%d%d", &l, &r);
		if(l == r)
		{
			if(l == 1 || prime(l) == 1) puts("No");
			else puts("Yes");
		}
		else if(r >= 100 && r - l > 50) puts("Yes");
		else
		{
			ll ans = 0;
			int bj = 0;
			int len = r - l + 1;
			for(int i = l; i <= r; i ++)
			{
				if(prime(i)) ans ++;
				if(ans * 3 >= len) 
				{
					puts("No");
					bj = 1;
					break;
				}
			}
			if(!bj) puts("Yes");
		}
	}
	return 0;
}

解法二
可以使用Robin-Miller 素数测试来判断素数,复杂度O(MAX log(n))。

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define fi first
#define se second
#define endl '\n'
#define Sezuna 0
#define IOS std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
using namespace std;

typedef long long ll;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e6 + 100;

 
long long PowerMod(long long a, long long b, long long k) 
{
    long long ret = 1, f = a;
 
    while (b) {
        if (b & 1)
            ret = ret * f % k;
        f = f * f % k;
        b >>= 1;
    }
    return ret;
}

bool MillerRobin(long long n,int MAX) 
{
    int i;
    long long tmp;
 
    srand(100);
    for (i = 0; i < MAX; i++) {
        tmp = rand() % (n - 1) + 1;
        if (PowerMod(tmp, n - 1, n) != 1)
            break;
    }
    return (i == MAX);
}

int main()
{
	int t;
	scanf("%d", &t);
	while(t --)
	{
		int bj = 0;
		ll l, r;
		ll ans = 0;
		scanf("%lld%lld", &l, &r);
        ll len = r - l + 1;
        if(l == r)
        {
            if(l == 1 || MillerRobin(l, 50) == 1) puts("No");
            else puts("Yes");
        }
        else if(r >= 100 && len > 100) puts("Yes");
        else
        {
            if(l == 1) l ++, ans ++;
            for(ll i = l; i <= r; i ++)
            {
                if(MillerRobin(i, 50)) ans ++;
                if(ans * 3 >= len) 
                {
                    puts("No");
                    bj = 1;
                    break;
                }
            }
            if(!bj) puts("Yes");
        }
	}
	return Sezuna;
}

F. The Answer to the Ultimate Question of Life, The Universe, and Everything.

题解:
真·打表题。
考虑暴力的复杂度是 枚举 a3 + b3的和(复杂度10000*10000),然后二分找c3是否存在,但是明显得先将c3排序,O(10000log(10000)),复杂度显然已经超出1s了。
仔细观察发现x的范围只有0 - 200,所以可以先将所有x对应的a b c的情况打表打出来,然后复制放到二维数组里,直接输出答案。

打表代码

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define fi first
#define se second
#define endl '\n'
#define Sezuna 0
#define IOS std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
#pragma GCC optimize(2) 
#pragma GCC optimize(3,"Ofast","inline")
using namespace std;

typedef long long ll;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e6 + 100;

unordered_map<ll, int> f;


ll g(ll x)  //
{
	//x可能为负,也可能为正,所以需要从-5000开始
	for(ll i = -5000; i <= 5000; i ++)  //这里的i得用ll,因为下面关系到i^3的运算
		if(i * i * i == x)
			return i;
}

bool find(int x)
{
	for(ll i = 0; i <= 5000; i ++)  //这里可以分类讨论,减少循环次数,不用从-5000开始
	{
		for(ll j = 0; j <= 5000; j ++)
		{
			//x = -i -j +g
			if(f.count(x + i * i * i + j * j * j)) //如果存在这个c^3
			{
				printf("%lld, %lld, %lld,\n", -i, -j, g(x + i * i * i + j * j * j));
				return true;
			}
			//x = +i +i -g
			else if(f.count(i * i * i + j * j * j - x)) //这里找的是正的g是否存在,而我们实际上的g是负的,所以开根之后要取负
			{
				// printf("%lld %lld %lld = %d\n",i,j,g(i*i*i+j*j*j-x),x);
				printf("%lld, %lld, %lld,\n", i, j, g(i * i * i + j * j * j - x) == 0 ? 0 : -g(i * i * i + j * j * j - x));
				return true;
			}
		}
	}
	return false;
}

int main()
{
	f.clear();
	 freopen("1.in", "w", stdout);
	for(ll i = -5000; i <= 5000; i ++)  //先用hash存下c^3的所有结果
		f[i * i * i] = 1;
	for(int i = 0; i <= 200; i ++)
	{
		if(!find(i)) printf("1111111111,0,0,\n");
		else continue;
	}
	return Sezuna;
}

AC代码:

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define fi first
#define se second
#define endl '\n'
#define Sezuna 0
#define IOS std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
using namespace std;

typedef long long ll;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e6 + 100;


int ans[205][3] = 
{
0, 0, 0,
0, 0, 1,
0, 1, 1,
1, 1, 1,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
-1, -1, 2,
0, -1, 2,
0, 0, 2,
0, 1, 2,
1, 1, 2,
-2, -2, 3,
7, 10, -11,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
2, 2, -1,
0, 2, 2,
1, 2, 2,
-1, -2, 3,
0, -2, 3,
1, 3, -2,
-11, -14, 16,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
2, 2, 2,
-1, -1, 3,
0, -1, 3,
0, 0, 3,
0, 1, 3,
1, 1, 3,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
2, 3, -1,
0, 2, 3,
1, 2, 3,
0, -3, 4,
1, 4, -3,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
2, 2, 3,
-5, -7, 8,
2, 4, -3,
3, 3, -2,
6, 7, -8,
-2, -2, 4,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
602, 659, -796,
1111111111,1111111111,1111111111,
-2, -4, 5,
0, 3, 3,
-1, -2, 4,
0, -2, 4,
1, 4, -2,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
-1, -4, 5,
0, -4, 5,
-1, -1, 4,
0, -1, 4,
0, 0, 4,
0, 1, 4,
1, 1, 4,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
2, 5, -4,
11, 20, -21,
2, 4, -1,
0, 2, 4,
1, 2, 4,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
26, 53, -55,
-19, -33, 35,
2, 2, 4,
3, 3, 3,
-11, -11, 14,
-2, -5, 6,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
-1972, -4126, 4271,
3, 5, -4,
6, 6, -7,
-1, -5, 6,
0, 3, 4,
1, 3, 4,
-5, -5, 7,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
14, 20, -22,
-1, -3, 5,
0, -3, 5,
1, 5, -3,
-3, -6, 7,
4, 4, -3,
118, 229, -239,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
-4, -7, 8,
2, 5, -3,
-28, -48, 51,
-948, -1165, 1345,
-2, -2, 5,
1111111111,1111111111,1111111111,
148, 1039, -1040,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
-6, -10, 11,
-1, -2, 5,
0, -2, 5,
1, 5, -2,
-2, -6, 7,
4, 4, -2,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
-1, -1, 5,
0, -1, 5,
0, 0, 5,
0, 1, 5,
0, -6, 7,
0, 4, 4,
1, 4, 4,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
2, 5, -1,
0, 2, 5,
1, 2, 5,
2, 7, -6,
2, 4, 4,
-9, -11, 13,
-77, -86, 103,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
2, 2, 5,
-3, -7, 8,
1111111111,1111111111,1111111111,
-2, -4, 6,
-7, -8, 10,
-5, -9, 10,
-50, -56, 67,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
260, 317, -367,
-1, -4, 6,
0, 3, 5,
1, 3, 5,
3, 7, -6,
3, 4, 4,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
80, 119, -130,
2, 3, 5,
-2, -7, 8,
-3, -3, 6,
-21, -26, 30,
-45, -47, 58,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
-1, -7, 8,
0, -7, 8,
1, 8, -7,
-5, -6, 8,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
7, 7, -8,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
2, 8, -7,
-10, -13, 15,
3, 3, 5,
1111111111,1111111111,1111111111,
-2, -3, 6,
9, 13, -14,
10, 16, -17,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
5, 5, -4,
27, 56, -58,
-1, -3, 6,
0, -3, 6,
1, 4, 5,
-3, -5, 7,
4, 4, 4,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
1111111111,1111111111,1111111111,
3, 8, -7,
2, 4, 5,
-19, -48, 49,
15, 22, -24,
-2, -2, 6,
};


int main()
{
	int t;
	scanf("%d", &t);
	while(t --)
	{
		int x;
		scanf("%d", &x);
		if(ans[x][0] == 1111111111) puts("impossible");
		else printf("%d %d %d\n", ans[x][0], ans[x][1], ans[x][2]);
	}
	return Sezuna;
}

Cat

(待补)
规律题。

用到的定理:

异或和定理:令f(n)表示从1到n的异或和,则:
      若n≡0(mod4),f(0,n)=n,
      若n≡1(mod4),f(0,n)=1,
      若n≡2(mod4),f(0,n)=n+1,
      若n≡3(mod4),f(0,n)=0。

若a是偶数,且a%4=(b+3)%4,则[a,b]的区间异或和为0。

异或运算的作用

参与运算的两个值,如果两个相应bit位相同,则结果为0,否则为1。

即:

0^0 = 0,

1^0 = 1,

0^1 = 1,

1^1 = 0

按位异或的3个特点:

(1) 0^0=0,0^1=1 0异或任何数=任何数

(2) 1^0=1,1^1=0 1异或任何数-任何数取反

(3) 任何数异或自己=把自己置0

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值