2012 ACM/ICPC Asia Regional Jinhua Online - hdu 4407

询问 x ~ y 与 p 互素的数字的和是多少。

因为询问+修改只有 1000 次,所以可以枚举修改的值。

1~n 有多少个数与p互素:将p拆成素因子,容斥定理搞一搞。

给出比赛时候的简陋代码。

View Code
  1 #include<cstdio>

  2 #include<iostream>

  3 #include<algorithm>

  4 #include<cstring>

  5 #include<climits>

  6 #include<cstdlib>

  7 #include<cmath>

  8 using namespace std;

  9 #define N 1010

 10 #define M 400010

 11 typedef __int64 ll;

 12 int prim[710], pr[710], top = 0, yi[20], tail;

 13 int id[M];

 14 struct node {

 15     int x, c;

 16 }qu[N];

 17 void S(){

 18     memset(prim,0,sizeof(prim));

 19     prim[1]=prim[0]=1;

 20     for(int i=2;i<=700;i++)

 21         if(!prim[i]){

 22             pr[top++] = i;

 23             for(int j=i*2;j<=700;j+=i)

 24                 prim[j]=1;

 25         }

 26 }

 27 int pri(int x) {

 28     int m = sqrt(1.0 * x), k = 0;

 29     for (int i = 0; i < top && pr[i] <= m; ++i) {

 30         if (x % pr[i] == 0) {

 31             x /= pr[i];

 32             yi[k++] = pr[i];

 33             while (x % pr[i] == 0) x /= pr[i];

 34         }

 35     }

 36     if (x != 1) yi[k++] = x;

 37     return k;

 38 }

 39 int Gcd(int a, int b)

 40 {

 41     if(b==0) return a;

 42     return Gcd(b,a%b);

 43 }

 44 ll find(int x, int n, int p) {

 45     ll ans = (ll)x*(x+1)/2;

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

 47         int t = i, k = 0, num = 0;

 48         ll temp = 1;

 49         while (t) {

 50             if (t&1) {

 51                 num++;

 52                 temp *= yi[k];

 53             }

 54             t >>= 1;

 55             ++k;

 56         }

 57         ll tb = ll(x)/temp;

 58         if (num&1) ans -= temp*(1+tb)*tb/2;

 59         else ans += temp*(1+tb)*tb/2;

 60     }

 61     for (int i = 0; i < tail; ++i) {

 62         if (qu[i].x > x) continue;

 63         int t2 = Gcd(qu[i].x, p);

 64         int t1 = Gcd(qu[i].c, p);

 65         if (t2 == 1) ans -= qu[i].x;

 66         if (t1 == 1) ans += qu[i].c;

 67     }

 68     return ans;

 69 }

 70 int main() {

 71     S();

 72     int T, n, m, f, x, y, c, p;

 73     scanf("%d", &T);

 74     while (T--) {

 75         memset(id, -1, sizeof(id));

 76         tail = 0;

 77         scanf("%d%d", &n, &m);

 78         while (m--) {

 79             scanf("%d", &f);

 80             if (f == 2) {

 81                 scanf("%d%d", &x, &c);

 82                 if (id[x] == -1) {

 83                     id[x] = tail;

 84                     qu[tail].x = x;

 85                     qu[tail].c = c;

 86                     tail++;

 87                 }

 88                 else {

 89                     qu[id[x]].x = x;

 90                     qu[id[x]].c = c;

 91                 }

 92             }

 93             else {

 94                 scanf("%d%d%d", &x, &y, &p);

 95                 int n = pri(p);

 96                 printf("%I64d\n", find(y, n, p)-find(x-1, n, p));

 97             }

 98         }

 99     }

100     return 0;

101 }

你可能感兴趣的:(online)