P1865 A % B Problem

题目背景

题目名称是吸引你点进来的

实际上该题还是很水的

题目描述

区间质数个数

输入输出格式

输入格式:

一行两个整数 询问次数n,范围m

接下来n行,每行两个整数 l,r 表示区间

输出格式:

对于每次询问输出个数 t,如l或r∉[1,m]输出 Crossing the line

输入输出样例

输入样例#1:

2 5
1 3
2 6

输出样例#1:

2
Crossing the line

说明

【数据范围和约定】

对于20%的数据 1<=n<=10 1<=m<=10

对于100%的数据 1<=n<=1000 1<=m<=1000000 -10^9<=l<=r<=10^9 1<=t<=1000000

其实就是想写写莫队练练(你信么),然而这个优雅的暴力还是超时一个点:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>

using namespace std;
const int N=1000010;

int answer[N],pos[N],become_answer;
bool vis[N];
int block,js,n,m;
struct node{
	int l,r,num;
}E[N];

inline int read()
{
	int x=0;int f=1;char c=getchar();
	while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
	while(c>=‘0‘&&c<=‘9‘)x=x*10+c-‘0‘,c=getchar();
	return x*f;
}

inline void important()
{
	for(int i=2;i<=sqrt(N+1);i++)
		if(!vis[i])
			for(int j=i*2;j<=N;j+=i)
				vis[j]=1;
	vis[0]=vis[1]=1;
}

inline bool cmp(node a,node b)
{
	if(pos[a.l]==pos[b.l])
		return a.r<b.r;
	else
		return a.l<b.l;
} 

inline void add(int x)
{
	if(!vis[x])
		become_answer++;
}

inline void dale(int x)
{
	if(!vis[x])
		become_answer--;
}

inline void MD()
{
	int l=1,r=1;
	for(int i=1;i<=js;i++)
	{   int ll=E[i].l,rr=E[i].r;
		for(;l<E[i].l;l++)dale(l);
		for(;l>E[i].l;l--)add(l-1);
		for(;r>E[i].r;r--)dale(r);
		for(;r<E[i].r;r++)add(r+1);
		answer[E[i].num]=become_answer;
	}
}

int main()
{
	important();
	n=read(),m=read();
	for(int i=1;i<=n;i++)
	{
		int l=read(),r=read();
		if(l<1||r<1||l>m||r>m)
			answer[i]=-1;
		else
		{
			E[++js].l=l;
			E[js].r=r;
			E[js].num=i;
		}
	}
	block=sqrt(m);
	for(int i=1;i<=m;i++)
		pos[i]=(i-1)/block+1;
	sort(E+1,E+js+1,cmp);
	MD();
	for(int i=1;i<=n;i++)
		if(answer[i]==-1)
			printf("Crossing the line\n");
		else
			printf("%d\n",answer[i]);

	return 0;
}

 水一波前缀和:

#include <cstdio>
#include<iostream>
#include<algorithm>

const int N=1000005;
using namespace std;

int n,m,l,r,s[N];

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=2;i<=m;i++)s[i]=1;
    for(int i=2;i*i<=m;i++)
        for(int j=i+i;j<=m;j+=i)
            s[j]=0;
	for(int i=1;i<=m;i++)
         s[i]+=s[i-1];
    while(scanf("%d%d",&l,&r)==2)
        (l<1||r>m)?printf("Crossing the line\n"):printf("%d\n",s[r]-s[l-1]);
}

  

时间: 2024-10-06 11:50:53

P1865 A % B Problem的相关文章

洛谷 P1865 A % B Problem(简单区间素数) 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problem/show?pid=1865 题目背景 题目名称是吸引你点进来的 实际上该题还是很水的 题目描述 区间质数个数 输入输出格式 输入格式: 一行两个整数 询问次数n,范围m 接下来n行,每行两个整数 l,r 表示区间 输出格式: 对于每次询问输出个数 t,如l或r∉[1,m]输出 Crossing the line 输入输出样例 输入样例#1: 2 5 1 3

【luogu P1865 A % B Problem】题解

题目链接:https://www.luogu.org/problemnew/show/P1865 其实就是埃拉托色尼筛素数模板... 好像每个数暴力枚举到sqrt()也可以...就算当我无聊练手罢 1 #include <cstdio> 2 #include <cmath> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 const int maxn = 1000000

【数论线性筛】洛谷P1865 A%B problem

题目背景 题目名称是吸引你点进来的 实际上该题还是很水的 题目描述 区间质数个数 输入输出格式 输入格式: 一行两个整数 询问次数n,范围m 接下来n行,每行两个整数 l,r 表示区间 输出格式: 对于每次询问输出个数 t,如l或r?[1,m]输出 Crossing the line 输入输出样例 输入样例#1: 2 5 1 3 2 6 输出样例#1: 2 Crossing the line 说明 [数据范围和约定] 对于20%的数据 1<=n<=10 1<=m<=10 对于100

洛谷 P1865 A % B Problem

题目背景 题目名称是吸引你点进来的 实际上该题还是很水的 题目描述 区间质数个数 输入输出格式 输入格式: 一行两个整数 询问次数n,范围m 接下来n行,每行两个整数 l,r 表示区间 输出格式: 对于每次询问输出个数 t,如l或r∉[1,m]输出 Crossing the line 输入输出样例 输入样例#1: 2 5 1 3 2 6 输出样例#1: 2 Crossing the line 说明 [数据范围和约定] 对于20%的数据 1<=n<=10 1<=m<=10 对于100

洛谷 P1865 A % B Problem (欧拉筛+前缀和)

题目背景 题目名称是吸引你点进来的 实际上该题还是很水的 题目描述 区间质数个数 输入输出格式 输入格式: 一行两个整数 询问次数n,范围m 接下来n行,每行两个整数 l,r 表示区间 输出格式: 对于每次询问输出个数 t,如l或r?[1,m]输出 Crossing the line 输入输出样例 输入样例#1: 2 5 1 3 2 6 输出样例#1: 2 Crossing the line 说明 [数据范围和约定] 对于20%的数据 1<=n<=10 1<=m<=10 对于100

2018-3刷题记录(to be continued)

3-1 P1880 [NOI1995]石子合并 3-2 P1508 Likecloud-吃.吃.吃 P1387 最大正方形 3-3 P1417 烹调方案 P1855 榨取kkksc03 P1736 创意吃鱼法 P1541 乌龟棋 3-4//留坑:高精.标签 P1203 [USACO1.1]坏掉的项链Broken Necklace P1582 倒水 P1338 末日的传说 P1372 又是毕业季I P1865 A % B Problem P1233 木棍加工 P1315 观光公交 P1080 国王

推荐题目

二分 P2678 跳石头 P2440 木材加工 P1873 砍树 P1577 切绳子 P1824 进击的奶牛 P1316 丢瓶盖 UVA1555 Garland P1257 平面上的最接近点对 P1429 平面最近点对(加强版)(未完成) P1182 数列分段"Section II" P1281 书的复制(二分做法和上题一样,只是输出值变成了输出划分方式) 递推 P2386 放苹果 P1025 数的划分 DP&&MS P1091 合唱队形 P1140 相似基因 P144

质数筛法详解

理论及实现 定义: 若一个正整数无法被除了1和它本身的之外的任何自然数整除,则称该为质数(素数),否则称该正整数为合数. 判定方法 试除法 引理: 若一个正整数\(N\)为合数,则存在一个能整除\(N\)的数\(T\)且\(2≤T≤ \sqrt N\) 证明就不再赘述,读者可以自行验证: 因此,我们只需要枚举\(2-\sqrt N\).只要这之中的所有数都不能被\(N\)整除,那么\(N\)就是质数了: #include<cmath> bool is_prime(int n) { if(n &

A Math Problem

A Math Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 237    Accepted Submission(s): 117 Problem Description You are given a positive integer n, please count how many positive integers