zoukankan      html  css  js  c++  java
  • [是题解哦] 洛谷 P1865 A % B Problem

    题目链接

    这里这里

    题目背景

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

    实际上该题还是很水的

    题目描述

    区间质数个数

    输入输出格式

    输入格式:

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

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

    输出格式:

    对于每次询问输出个数 t,如l或r∉[1,m]输出 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

    题解

    由于涉及到区间查询操作,这道题我使用埃筛+线段树来做

    我使用毒瘤的动态开点的方式进行建树操作

    首先在建树前进行一次筛选,得到一张质数表,再根据质数表建树,如下

     1 void GetList(int m){
     2     for(int i=2;i<=m;i++)
     3         Prime[i]=true;
     4     Prime[0]=false;
     5     Prime[1]=false;
     6     for(int i=2;i<=m;i++){
     7         if(!Prime[i])
     8             continue;
     9         else
    10             for(int j=i*2;j<=m;j+=i)
    11                 Prime[j]=false;
    12     }
    13 }
    14 
    15 void Build(int &now,int l,int r,int x,int k){
    16     if(now==0)
    17         now=++cnt;
    18     if(l==r){
    19         Seg[now].sum=k;
    20         return;
    21     }
    22     int mid=(l+r)>>1;
    23     if(x<=mid)
    24         Build(Seg[now].L,l,mid,x,k);
    25     else
    26         Build(Seg[now].R,mid+1,r,x,k);
    27     Seg[now].sum=Seg[Seg[now].L].sum+Seg[Seg[now].R].sum;
    28 }
    29 
    30     GetList(m);
    31     for(int i=1;i<=m;i++)
    32         if(Prime[i]==true)
    33             Build(root,1,m,i,1);//如果是质数,就把该点标记为1
    34         else
    35             Build(root,1,m,i,0);//如果不是质数,就标记为0

    建树时这样操作,查询就可以和普通的线段树一样维护了

    下面是完整代码

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 
     5 struct node{
     6     int sum;
     7     int L;
     8     int R;
     9 }Seg[4000010];
    10 int root,cnt,n,m;
    11 bool Prime[1000010];
    12 
    13 void GetList(int m){
    14     for(int i=2;i<=m;i++)
    15         Prime[i]=true;
    16     Prime[0]=false;
    17     Prime[1]=false;
    18     for(int i=2;i<=m;i++){
    19         if(!Prime[i])
    20             continue;
    21         else
    22             for(int j=i*2;j<=m;j+=i)
    23                 Prime[j]=false;
    24     }
    25 }
    26 
    27 void Build(int &now,int l,int r,int x,int k){
    28     if(now==0)
    29         now=++cnt;
    30     if(l==r){
    31         Seg[now].sum=k;
    32         return;
    33     }
    34     int mid=(l+r)>>1;
    35     if(x<=mid)
    36         Build(Seg[now].L,l,mid,x,k);
    37     else
    38         Build(Seg[now].R,mid+1,r,x,k);
    39     Seg[now].sum=Seg[Seg[now].L].sum+Seg[Seg[now].R].sum;
    40 }
    41 
    42 int Query(int now,int l,int r,int x,int y){
    43     if(x<=l && r<=y)
    44         return Seg[now].sum;
    45     int mid=(l+r)>>1;
    46     int sumL=0,sumR=0;
    47     if(x<=mid)
    48         sumL+=Query(Seg[now].L,l,mid,x,y);
    49     if(y>mid)
    50         sumR+=Query(Seg[now].R,mid+1,r,x,y);
    51     return sumL+sumR;
    52 }
    53 
    54 int main(){
    55     scanf("%d%d",&n,&m);
    56     GetList(m);
    57     for(int i=1;i<=m;i++)
    58         if(Prime[i]==true)
    59             Build(root,1,m,i,1);
    60         else
    61             Build(root,1,m,i,0);
    62     for(int i=1;i<=n;i++){
    63         register int p,q;
    64         scanf("%d%d",&p,&q);
    65         if(p<1 || p>m || q<1 || q>m)
    66             printf("Crossing the line
    ");
    67         else
    68             printf("%d
    ",Query(root,1,m,p,q));
    69     }
    70     return 0;
    71 }


    友情链接:安利一只小姐姐的博客

  • 相关阅读:
    k-means聚类JAVA实例
    钓鱼站点以世界杯足球赛为饵,收集个人资料
    南桥--特殊回文数
    Oracle 数据文件管理
    hihoCoder #1142 : 三分求极值
    时间复杂度和空间复杂度[数据结构]
    poj 3635 Full Tank? ( 图上dp )
    FastQC结果详解
    毕业设计常见问题
    centos 查看USB接口的版本
  • 原文地址:https://www.cnblogs.com/tatarakogasa/p/9782870.html
Copyright © 2011-2022 走看看