• HOJ 1867 经理的烦恼 树状数组


    /*

    题目:

       给出n个商店,每个商店有初始化的商品数量,现在有两种指令:

       0 x y 连锁店x的商品数量变化值为y,y > 0商品数量增加, y < 0减少

       1 i j 输出编号在[i,j]区间内的连锁店中商品数量为素数的有多少家

       当指令为1时,求给出 i到j的商品数量为素数的商店的数目

     

    分析:

       用树状数组做,只不过在update()处改动一下,并且注意到有可能改动完后和改动前

       均为素数的情况,所以用visit[]数组记录此前是否为素数,另外需要注意的是当初始

       化时即为奇数的话,当时就要初始化数组c[]以及visit[]数组

    */

    #include <iostream>

    #include <cstdio>

    #include <cstring>

    using namespace std;

    const int X = 1000010;

    int a[X],c[X],n,m,k;

    bool visit[X];

    bool check(int x)  //判断是否是素数

    {

       if(x<=1)    //小于等于一直接返回false

          return false;

       for(int i=2;i*i<=x;i++)

          if(x%i==0)

             return false;

       return true;

    }

    int lowbit(int x)

    {

       return x & -x;

    }

    int sum(int x)        //求和

    {

       int ans = 0;

       while(x>0)

       {

          ans += c[x];

          x -= lowbit(x);

       }

       return ans;

    }

    void update(int x)

    {

       if(check(a[x]))       //如果这个商店的商品数为素数

       {

          if(!visit[x])      //如果之前不是素数的话,现在为素数

          {

             visit[x] = true;

             while(x<=n)

             {

                c[x]++;

                x += lowbit(x);

             }

          }

       }

       else               //如果这个商店的商品数为偶数

       {

          if(visit[x])    //如果之前是素数,但现在不是素数

          {

             visit[x] = false;

             while(x<=n)

             {

                c[x]--;

                x += lowbit(x);

             }

          }

       }

    }

    int main()

    {

       freopen("sum.in","r",stdin);

       freopen("sum.out","w",stdout);

       int x,y,z,cnt = 0;

       while(scanf("%d%d%d",&n,&m,&k),n||m||k)

       {

          printf("CASE #%d:\n",++cnt);

          for(int i=1;i<=n;i++)    //初始化

             a[i] = k;

          if(check(k))          //如果刚开始即为素数

          {

             for(int i=1;i<=n;i++)

             {

                c[i] = lowbit(i);

                visit[i] = true;   //visit数组为true时表示之前的数为素数

             }

          }

          else

          {

             memset(c,0,sizeof(c));

             memset(visit,false,sizeof(visit));

          }

          for(int i=1;i<=m;i++)

          {

             scanf("%d%d%d",&z,&x,&y);

             if(z)

                printf("%d\n",sum(y)-sum(x-1));

             //计算的是[i,j]的区间内的连锁店中商品数量为素数的有多少家

     

             else

             {

                a[x] += y;         //x商店的变化

                update(x);         //更新x商店的变化给其他商店带来的变化

             }

          }

          cout<<endl;

       }

       return 0;

    }

  • 相关阅读:
    程序员私活话题
    关于未来房价
    关于.net core 中的signalR组件的使用
    typescript nodejs 依赖注入实现
    .net core mvc启动顺序以及主要部件4-MVC
    .net core mvc启动顺序以及主要部件3-Startup
    .net core mvc启动顺序以及主要部件2
    .net core mvc启动顺序以及主要部件1
    关于.NET HttpClient方式获取微信小程序码(二维码)
    ASP.NETCore 3.0 Autofac替换及控制器属性注入及全局容器使用
  • 原文地址:https://www.cnblogs.com/yejinru/p/2411671.html
Copyright © 2020-2023  润新知