• Bzoj 3813 奇数国 题解 数论+线段树+状压


    3813: 奇数国

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 748  Solved: 425
    [Submit][Status][Discuss]

    Description

    在一片美丽的大陆上有100000个国家,记为1到100000。这里经济发达,有数不尽的账房,并且每个国家有一个银行。某大公司的领袖在这100000个银行开户时都存了3大洋,他惜财如命,因此会不时地派小弟GFS清点一些银行的存款或者让GFS改变某个银行的存款。该村子在财产上的求和运算等同于我们的乘法运算,也就是说领袖开户时的存款总和为3100000。这里发行的软妹面额是最小的60个素数(p1=2,p2=3,…,p60=281),任何人的财产都只能由这60个基本面额表示,即设某个人的财产为fortune(正整数),则fortune=p1^k1*p2^k2*......p60^K60。
     
    领袖习惯将一段编号连续的银行里的存款拿到一个账房去清点,为了避免GFS串通账房叛变,所以他不会每次都选择同一个账房。GFS跟随领袖多年已经摸清了门路,知道领袖选择账房的方式。如果领袖选择清点编号在[a,b]内的银行财产,他会先对[a,b]的财产求和(计为product),然后在编号属于[1,product]的账房中选择一个去清点存款,检验自己计算是否正确同时也检验账房与GFS是否有勾结。GFS发现如果某个账房的编号number与product相冲,领袖绝对不会选择这个账房。怎样才算与product不相冲呢?若存在整数x,y使得number*x+product*y=1,那么我们称number与product不相冲,即该账房有可能被领袖相中。当领袖又赚大钱了的时候,他会在某个银行改变存款,这样一来相同区间的银行在不同的时候算出来的product可能是不一样的,而且领袖不会在某个银行的存款总数超过1000000。
     
    现在GFS预先知道了领袖的清点存款与变动存款的计划,想请你告诉他,每次清点存款时领袖有多少个账房可以供他选择,当然这个值可能非常大,GFS只想知道对19961993取模后的答案。

    Input

    第一行一个整数x表示领袖清点和变动存款的总次数。
    接下来x行,每行3个整数ai,bi,ci。ai为0时表示该条记录是清点计划,领袖会清点bi到ci的银行存款,你需要对该条记录计算出GFS想要的答案。ai为1时表示该条记录是存款变动,你要把银行bi的存款改为ci,不需要对该记录进行计算。

    Output

    输出若干行,每行一个数,表示那些年的答案。

    Sample Input

    6
    013
    115
    013
    117
    013
    023

    Sample Output

    18
    24
    36
    6
    explanation
    初始化每个国家存款都为3;
    1到3的product为27,[1,27]与27不相冲的有18个数;
    1的存款变为5;
    1到3的product为45,[1,45]与45不相冲的有24个数;
    1的存款变为7;
    1到3的product为63,[1,63]与63不相冲的有36个数;
    2到3的product为9,[1,9]与9不相冲的有6个数。

    HINT

    x≤100000,当ai=0时0≤ci−bi≤100000

    Source

      这是一道好题啊……
      题目里的每一句话都暗藏玄机……
      题目关键点在于number与product的关系,number*x+product*y=1的条件就是他们互质,所以我们实际要求的是porduct的欧拉函数。当然了,线筛肯定滚粗,我们还得看题目。他说任何人的财产都可以用那60个素数表示,良心啊。这样我们就可以用唯一分解来求欧拉函数了。
      但是,问题在于我们怎么去求他的因子呢?线段树求出来的是在模完之后的,不可能通过它去求。所以我们还得维护一下因子。
      由于博主太过蒟蒻,所以傻乎乎的拿了一个bool数组去存,然后T到死……
      没办法,只能怂一波。万万没想到,一个long long就可以解决了。不知道大家有没有对本题涉及到的质数的个数60感到好奇呢?是的,long long极限是2^63-1,所以long long状压刚好可以,所以我们只要在线段树里用一个long long状压表示因子有谁就好了。
      1 #include <iostream>
      2 #include <cstdlib>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <algorithm>
      6 #include <cmath>
      7 #include <queue>
      8 #include <map>
      9 #include <vector>
     10 #define N 100005
     11 using namespace std;
     12 int n,p=19961993;
     13 long long ksm(long long x,long long z)
     14 {
     15     long long ans=1;
     16     while(z)
     17     {
     18         if(z&1)
     19         {
     20             ans*=x;
     21             ans%=p;
     22         }
     23         x*=x;x%=p;
     24         z>>=1;
     25     }
     26     return ans;
     27 }
     28 int zz,ss[100];
     29 struct no{
     30     int left,right,mid;
     31     long long data,pp;
     32 }node[N*4];
     33 void build(int left,int right,int x)
     34 {
     35     node[x].left=left,node[x].right=right;
     36     node[x].pp|=(1<<1ll);
     37     if(left==right)
     38     {
     39         node[x].data=3;
     40         return;
     41     }
     42     int mid=(left+right)>>1;
     43     node[x].mid=mid;
     44     build(left,mid,x*2);
     45     build(mid+1,right,2*x+1);
     46     node[x].data=node[2*x].data*node[2*x+1].data;
     47     node[x].data%=p;
     48 }
     49 void change(int to,int x,long long z)
     50 {
     51     if(node[x].left==node[x].right)
     52     {
     53         node[x].data=z;
     54         node[x].pp=0;
     55         for(int i=1;i<=zz;i++)
     56         {
     57             if(z%ss[i]==0) node[x].pp|=(1ll<<(i-1ll));
     58         }
     59         return;
     60     }
     61     int mid=node[x].mid;
     62     if(to>mid)change(to,2*x+1,z);
     63     else change(to,2*x,z);
     64     node[x].data=node[2*x].data*node[2*x+1].data;
     65     node[x].data%=p;
     66     node[x].pp=node[2*x].pp|node[2*x+1].pp;
     67 }
     68 long long pp;
     69 long long get(int left,int right,int x)
     70 {
     71     if(node[x].left==left&&node[x].right==right)
     72     {
     73         pp|=node[x].pp;
     74         return node[x].data;
     75     }
     76     int mid=node[x].mid;
     77     if(left>mid)return get(left,right,2*x+1);
     78     else if(right<=mid)return get(left,right,2*x);
     79     else return get(left,mid,2*x)*get(mid+1,right,2*x+1)%p;
     80 }
     81 long long ni[100];
     82 void init()
     83 {
     84     for(int i=2;zz<60;i++)
     85     {
     86         zz++;
     87         ss[zz]=i;
     88         for(int j=2;j<=sqrt(i);j++)
     89         {
     90             if(i%j==0)
     91             {
     92                 ss[zz]=0;
     93                 zz--;
     94                 break;
     95             }
     96         }
     97     }
     98     for(int i=1;i<=60;i++)ni[i]=ksm(ss[i],p-2);
     99 }
    100 int main()
    101 {
    102     init();
    103     scanf("%d",&n);
    104     build(1,100000,1);
    105     for(int i=1;i<=n;i++)
    106     {
    107         int op;
    108         scanf("%d",&op);
    109         if(op)
    110         {
    111             long long x,y;
    112             scanf("%lld%lld",&x,&y);
    113             change(x,1,y);
    114         }
    115         else
    116         {
    117             long long x,y;
    118             pp=0;
    119             scanf("%d%d",&x,&y);
    120             long long pro=get(x,y,1);
    121             long long ans=pro;
    122             for(int i=1;i<=zz;i++)
    123             {
    124                 if(pp&(1ll<<(i-1ll)))
    125                 {
    126                     ans*=ni[i];
    127                     ans%=p;
    128                     ans*=(ss[i]-1);
    129                     ans%=p;
    130                 }
    131             }
    132             printf("%lld
    ",ans);
    133         }
    134     }
    135     return 0;
    136 }
    View Code
  • 相关阅读:
    [mysql练习]多行结果合并问题练习
    【Python】Python多进程练习
    【mysql练习】转置,总计,分组
    【Mysql】HDFS文件上传流程
    [Jmeter][基础]Jmeter连接IMPALA
    【Linux】 -bash-4.2#问题和Cannot allocate memory
    微服务学习之路
    好的东西一定要收藏-持续更新
    Python日期的加减等操作
    NGINX动态增加模块,平滑升级
  • 原文地址:https://www.cnblogs.com/liutianrui/p/7703639.html
Copyright © 2020-2023  润新知