• hdu 5152 A Strange Problem(题意分析)线段树+欧拉函数


    *****************************************BC题解**********************************************************************
    1003 A Strange Problem 对于操作二,利用公式 当x >= Phi(C), A^x = A ^ (x%Phi(C) + Phi(C)) (mod C) 对于2333333这个模数来说,求18次欧拉函数后就变成了1,所以只需要保存19层第三次操作的加数即可,然后就直接是线段树区间更新和询问操作了。 Ps:很多人把题目想简单了,操作二不能直接简单的更新,不满足2^(2^x) mod P = 2^( 2^x mod P) mod P。
    *********************************************************************************************************************
    看了一下数论,终于明白什么意思了,数学功底差+书看的少就是捉急。
    讨论里边看人问A不了,问题出在哪里,答曰2333333。当成笑话看了。。真是讽刺。。

    为了看懂翻译你需要知道:欧拉函数,欧拉定理

    下面是题解的翻译:

    因为2333333不是素数,所以在2^(2^x) mod P 的时候会出现问题,不等于2^( 2^x mod P) mod P,那怎么办呢,题解第二行已给出公式A^x = A ^ (x%Phi(C) + Phi(C)) (mod C)。
    证明可见:http://hi.baidu.com/aekdycoin/item/e493adc9a7c0870bad092fd9

    这里最好打表解决,但是可以顺便学一下欧拉函数的实现
     1 #include<stdio.h>
     2 #include<string.h>
     3 int haha(int n)//求n的欧拉函数值
     4 {
     5     int res=n,i,j;
     6     for(i=2;i*i<=n;i++)
     7     {
     8         if(n%i==0)
     9         {
    10             n=n/i;
    11             while(n%i==0)
    12                 n=n/i;
    13             res=res/i*(i-1);
    14         }
    15         if(n<(i+1))
    16             break;
    17     }
    18     if(n>1)
    19         res=res/n*(n-1);
    20     return res;
    21 }
    22 int main()
    23 {
    24     int T,n,m,i,sum;
    25     while(scanf("%d",&T)!=EOF)
    26     {
    27         while(T--)
    28         {
    29           sum=0;
    30           scanf("%d%d",&n,&m); 
    31           for(i=1;i*i<=n;i++)
    32               if(n%i==0)
    33               {
    34                   if(i>=m)
    35                       sum=sum+haha(n/i);
    36                   if((n/i)!=i&&(n/i)>=m)
    37                       sum=sum+haha(i);
    38               }
    39           printf("%d
    ",sum);
    40         }
    41     }
    42     return 0;
    43 }
    欧拉函数
      1 #include <cstdio>
      2 #include <cstring>
      3 #include <vector>
      4 #include <algorithm>
      5 #include <ctime>
      6 #include <iostream>
      7 using namespace std;
      8 
      9 typedef __int64 ll;
     10 const int MOD = 2333333;
     11 const int N = 50000+5;
     12 
     13 int mo[20] = {2333333,2196720,580608,165888,55296,18432,
     14 6144,2048,1024,512,256,128,64,32,16,8,4,2,1};
     15 int pow2[33];
     16 
     17 vector<ll> vt[N];
     18 struct Segtree {
     19 #define lson rt<<1, l, mid
     20 #define rson rt<<1|1, mid+1, r
     21     ll mark[N<<2];
     22     int length[N<<2], sum[N<<2];
     23     void build(int rt, int l, int r) {
     24         mark[rt] = 0;
     25         length[rt] = r-l+1;
     26         if(l == r) {
     27             vt[l].clear();
     28             int x;
     29             scanf("%d", &x);
     30             vt[l].push_back(x);
     31             sum[rt] = x%MOD;
     32             return ;
     33         }
     34         int mid = l+r>>1;
     35         build(lson); build(rson);
     36         up(rt);
     37     }
     38 
     39     inline void Add(int &x, int y) {
     40         x += y;
     41         if(x >= MOD)    x -= MOD;
     42     }
     43 
     44     void up(int rt) {
     45         sum[rt] = sum[rt<<1] + sum[rt<<1|1];
     46         Add(sum[rt], 0);
     47     }
     48 
     49     void down(int rt) {
     50         if(mark[rt]) {
     51             mark[rt<<1] += mark[rt];
     52             mark[rt<<1|1] += mark[rt];
     53             Add(sum[rt<<1], 1LL*length[rt<<1]*mark[rt]%MOD);
     54             Add(sum[rt<<1|1], 1LL*length[rt<<1|1]*mark[rt]%MOD);
     55             mark[rt] = 0;
     56         }
     57     }
     58 
     59     void update(int rt, int l, int r, int L, int R, int v) {
     60         if(L <= l && R >= r) {
     61             mark[rt] += v;
     62             Add(sum[rt], 1LL*length[rt]*v%MOD);
     63             return ;
     64         }
     65         down(rt);
     66         int mid = l+r>>1;
     67         if(L <= mid)    update(lson, L, R, v);
     68         if(R > mid) update(rson, L, R, v);
     69         up(rt);
     70     }
     71 
     72     int pow_mod(int x, int n, int mod) {
     73         int ret = 1%mod;
     74         while(n) {
     75             if(n&1) ret = 1LL*ret*x%mod;
     76             x = 1LL*x*x%mod;
     77             n >>= 1;
     78         }
     79         return ret;
     80     }
     81 
     82     int cal(vector<ll> &v) {
     83         if(v.size() < 19) {
     84             int pos = v.size()-1;
     85             ll ret = v[0];
     86             bool flag = false;
     87             if(v[0] >= mo[pos]) {
     88                 flag = true;
     89                 ret = ret%mo[pos] + mo[pos];
     90             }
     91             pos--;
     92             for(int i = 1;i < v.size(); i++) {
     93                 if(flag) {
     94                     ret = (pow_mod(2, ret, mo[pos]) +v[i])%mo[pos] + mo[pos];
     95                 }
     96                 else {
     97                     if(ret >= 30) {
     98                         flag = true;
     99                         ret = (pow_mod(2, ret, mo[pos]) + v[i])%mo[pos]+mo[pos];
    100                     }
    101                     else if(pow2[ret] >= mo[pos]) {
    102                         flag = true;
    103                         ret = (pow_mod(2, ret, mo[pos]) + v[i])%mo[pos] + mo[pos];
    104                     }
    105                     else {
    106                         ret = pow2[ret] + v[i];
    107                         if(ret >= mo[pos]) {
    108                             flag = true;
    109                             ret = ret%mo[pos] + mo[pos];
    110                         }
    111                     }
    112                 }
    113                 pos--;
    114             }
    115             return ret%MOD;
    116         }
    117         else {
    118             ll ret = 1;
    119             int pos = 18;
    120             bool flag = true;
    121             for(int i = v.size()-18;i < v.size(); i++) {
    122                 ret = (pow_mod(2, ret, mo[pos]) + v[i])%mo[pos] + mo[pos];
    123                 pos--;
    124             }
    125             return ret%MOD;
    126         }
    127     }
    128 
    129     void modify(int rt, int l, int r, int x) {
    130         if(l == r) {
    131             if(mark[rt]) {
    132                 vt[l][vt[l].size()-1] += mark[rt];
    133                 mark[rt] = 0;
    134             }
    135             vt[l].push_back(0);
    136             sum[rt] = cal(vt[l]);
    137             return ;
    138         }
    139         down(rt);
    140         int mid = l+r>>1;
    141         if(x <= mid)    modify(lson, x);
    142         else    modify(rson, x);
    143         up(rt);
    144     }
    145 
    146     int query(int rt, int l, int r, int L, int R) {
    147         if(L <= l && R >= r)    return sum[rt];
    148         down(rt);
    149         int mid = l+r>>1, ret = 0;
    150         if(L <= mid)    Add(ret, query(lson, L, R));
    151         if(R > mid) Add(ret, query(rson, L, R));
    152         up(rt);
    153         return ret;
    154     }
    155 }tree;
    156 
    157 int n, m;
    158 
    159 void init() {
    160     for(int i = 0;i <= 30; i++) pow2[i] = 1<<i;
    161 }
    162 
    163 int main() {
    164     init();
    165     int op, l, r, x;
    166     while(scanf("%d%d", &n, &m) == 2) {
    167         tree.build(1, 1, n);
    168         while(m--) {
    169             scanf("%d", &op);
    170             if(op == 1) {
    171                 scanf("%d%d", &l, &r);
    172                 printf("%d
    ", tree.query(1, 1, n, l, r));
    173             }
    174             else if(op == 2) {
    175                 scanf("%d", &x);
    176                 tree.modify(1, 1, n, x);
    177             }
    178             else {
    179                 scanf("%d%d%d", &l, &r, &x);
    180                 tree.update(1, 1, n, l, r, x);
    181             }
    182         }
    183     }
    184     return 0;
    185 }
    代码君
    
    
  • 相关阅读:
    poj2388-Who's in the Middle(排序)
    poj1543-Perfect Cubes(暴力)
    poj1664-放苹果(递归)
    快速幂
    poj2389-Bull Math(大整数乘法)
    HDU2608-0 or 1(数论+找规律)
    poj1131-Octal Fractions(进制转换)
    [noip2011 d1t2]选择客栈
    [周记]8.7~8.16
    [noip2012d1t2] 国王游戏
  • 原文地址:https://www.cnblogs.com/usedrosee/p/4189664.html
Copyright © 2020-2023  润新知