zoukankan      html  css  js  c++  java
  • BZOJ3813 奇数国

    即求区间的乘积的欧拉函数模一个数

    预处理前60个素数和逆元,用线段树维护区间乘机和每个素数出现的次数(我用了bitset嗯嗯嗯)

    于是可以O(sqrt(n))求出欧拉函数

      1 /**************************************************************
      2     Problem: 3813
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:1644 ms
      7     Memory:8624 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <bitset>
     12  
     13 using namespace std;
     14 typedef long long ll;
     15 const int mod = 19961993;
     16 const int N = 1e5 + 5;
     17  
     18 struct segment{
     19     ll v;
     20     bitset <65> ap;
     21 } seg[N << 2];
     22  
     23 int n, m;
     24 ll v;
     25 bitset <65> ap;
     26 int pr[65], tot;
     27 ll inv[65];
     28 bool vis[305];
     29  
     30 inline int read() {
     31     int x = 0;
     32     char ch = getchar();
     33     while (ch < '0' || '9' < ch)
     34         ch = getchar();
     35     while ('0' <= ch && ch <= '9') {
     36         x = x * 10 + ch - '0';
     37         ch = getchar();
     38     }
     39     return x;
     40 }
     41  
     42 inline ll pow(ll x, int y) {
     43     ll res = 1;
     44     while (y) {
     45         if (y & 1) res = res * x % mod;
     46         x = x * x % mod;
     47         y >>= 1;
     48     }
     49     return res;
     50 }
     51  
     52 void pre_work() {
     53     int i, j;
     54     for (i = 2; tot <= 60; ++i)
     55         if (!vis[i]) {
     56             pr[++tot] = i;
     57             for (j = i; j <= 300; j += i) vis[j] = 1;
     58         }
     59     for (i = 1; i <= 60; ++i)
     60         inv[i] = 1ll * pow(pr[i], mod - 2) * (pr[i] - 1) % mod;
     61 }
     62  
     63 #define Ls (p << 1)
     64 #define Rs (p << 1 | 1)
     65 #define mid (l + r >> 1)
     66 inline void update(int p) {
     67     seg[p].v = seg[Ls].v * seg[Rs].v % mod;
     68     seg[p].ap = seg[Ls].ap | seg[Rs].ap;
     69 }
     70  
     71 void seg_build(int p, int l, int r) {
     72     if (l == r) {
     73         seg[p].v = 3, seg[p].ap[2] = 1;
     74         return;
     75     }
     76     seg_build(Ls, l, mid), seg_build(Rs, mid + 1, r);
     77     update(p);
     78 }
     79  
     80 void seg_modify(int p, int l, int r, int pos, int v) {
     81     if (l == r) {
     82         int i;
     83         seg[p].v = v, seg[p].ap.reset();
     84         for (i = 1; i <= 60; ++i)
     85             if (v % pr[i] == 0) seg[p].ap[i] = 1;
     86         return;
     87     }
     88     if (pos <= mid) seg_modify(Ls, l, mid, pos, v);
     89     else seg_modify(Rs, mid + 1, r, pos, v);
     90     update(p);
     91 }
     92  
     93 void seg_query(int p, int l, int r, int L, int R) {
     94     if (L <= l && r <= R) {
     95         v = v * seg[p].v % mod, ap |= seg[p].ap;
     96         return;
     97     }
     98     if (L <= mid) seg_query(Ls, l, mid, L, R);
     99     if (mid < R) seg_query(Rs, mid + 1, r, L, R);
    100 }
    101 #undef mid
    102 #undef Ls
    103 #undef Rs
    104  
    105 int main() {
    106     int oper, x, y, i;
    107     pre_work();
    108     n = 1e5;
    109     seg_build(1, 1, n);
    110     m = read();
    111     while (m--) {
    112         oper = read(), x = read(), y = read();
    113         if (oper) seg_modify(1, 1, n, x, y);
    114         else {
    115             v = 1, ap.reset();
    116             seg_query(1, 1, n, x, y);
    117             for (i = 1; i <= 60; ++i)
    118                 if (ap[i]) v = v * inv[i] % mod;
    119             printf("%lld
    ", v);
    120         }
    121     }
    122     return 0;
    123 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    编程爱好者论坛第六次编程比赛题目
    google china code jam round2 div1 1000分题
    ogl2dlibsdl cvs repository @ cosoft
    偶尔也提一个游戏点子:宇宙碰撞
    今天看到一些笑话...
    google china code jam入围赛的一个题
    用Regular expression寻找源代码中的汉字字符串
    生成函数理论初步
    Komodo 的中文支持
    “豪华版”的USB延长线
  • 原文地址:https://www.cnblogs.com/rausen/p/4333260.html
Copyright © 2011-2022 走看看