• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
slon
nit-acm
博客园    首页    新随笔    联系   管理    订阅  订阅

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 }
posted @ 2012-09-22 19:03  slon  阅读(825)  评论(3)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3