Sum

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2974    Accepted Submission(s): 843

Problem Description
XXX is puzzled with the question below:

1, 2, 3, ..., n (1<=n<=400000) are placed in a line. There are m (1<=m<=1000) operations of two kinds.

Operation
1: among the x-th number to the y-th number (inclusive), get the sum of
the numbers which are co-prime with p( 1 <=p <= 400000).
Operation 2: change the x-th number to c( 1 <=c <= 400000).

For each operation, XXX will spend a lot of time to treat it. So he wants to ask you to help him.
 
Input
There are several test cases.
The first line in the input is an integer indicating the number of test cases.
For each case, the first line begins with two integers --- the above mentioned n and m.
Each the following m lines contains an operation.
Operation 1 is in this format: "1 x y p".
Operation 2 is in this format: "2 x c".
 
Output
For each operation 1, output a single integer in one line representing the result.
 
Sample Input
1
3 3
2 2 3
1 1 3 4
1 2 3 6
 
Sample Output
7
0
思路:容斥原理;
因为原数列是[1,n];所以数的和我们可以直接用求和公式;
然后m<1000;所以改变的最多不超过1000;我们用数组存改变,改变的位置会重复,这时后要覆盖,也就是数组中原先已有这个点,我们可以用map标记是否在数组中已有;
没有的话加入,有的话覆盖。
然后询问是[x,y]区间内与z互质的数的和,所以我们考虑分解z,那么素数打表。
然后容斥求在[x,y]与z互质数的和;然后再循环一遍改变,判断替换的数,和原来的数是否与z互质,原来的数互质的话减去原来的,改变的数互质的话,加上改变的数;
每个数的不同的质因数不超过9个;
复杂度(5120*m);
  1 #include<stdio.h>
2 #include<algorithm>
3 #include<iostream>
4 #include<stdlib.h>
5 #include<string.h>
6 #include<queue>
7 #include<map>
8 typedef long long LL;
9 using namespace std;
10 bool prime[400005];
11 int ans[400005];
12 queue<int>que;
13 int cm[400005];
14 int ma[400005];
15 int flag[2000];
16 int gcd(int n,int m);
17 map<int,int>my;
18 int main(void)
19 {
20 int i,j,k;
21 int p,q;
22 int n,m;
23 int x,y;
24 int t;
25 for(i=2; i<=2000; i++)
26 {
27 if(!prime[i])
28 {
29 for(j=i; i*j<=400000; j++)
30 {
31 prime[i*j]=true;
32 }
33 }
34 }
35 int cnt=0;
36 for(i=2; i<=400000; i++)
37 {
38 if(!prime[i])
39 {
40 ans[cnt++]=i;
41 }
42 }
43 scanf("%d",&k);
44 while(k--)
45 { my.clear();
46 scanf("%d %d",&p,&q);
47 int bt=1;
48 for(i=0; i<=p; i++)
49 ma[i]=i;
50 while(q--)
51 {
52 scanf("%d",&n);
53 if(n==1)
54 {
55 scanf("%d %d %d",&x,&y,&t);
56 int r=0;
57 int yy=0;
58 int xy=t;
59 if(x>y)swap(x,y);
60 while(t>1)
61 {
62 if(r==0&&t%ans[yy]==0)
63 {
64 r=1;
65 que.push(ans[yy]);
66 t/=ans[yy];
67 }
68 else if(r==1&&t%ans[yy]==0)
69 {
70 t/=ans[yy];
71 }
72 else
73 {
74 r=0;
75 yy++;
76 }
77 }
78 x-=1;
79 int ak=0;
80 while(!que.empty())
81 {
82 cm[ak++]=que.front();
83 que.pop();
84 }
85 LL sum1=0;
86 LL sum2=0;
87 for(i=1; i<=(1<<ak)-1; i++)
88 {
89 int nn=0;
90 LL dp=1;
91 for(j=0; j<ak; j++)
92 {
93 if(i&(1<<j))
94 {
95 nn++;
96 dp*=(LL)cm[j];
97 }
98 }
99 if(nn%2)
100 {
101 LL ct=y/dp;
102 LL qt=x/dp;
103 LL ct1=ct+1;
104 LL qt1=qt+1;
105 sum1+=dp*ct1*ct/2;
106 sum2+=dp*qt1*qt/2;
107 }
108 else
109 {
110 LL ct=y/dp;
111 LL qt=x/dp;
112 LL ct1=ct+1;
113 LL qt1=qt+1;
114 sum1-=dp*ct1*ct/2;
115 sum2-=dp*qt1*qt/2;
116 }
117 } LL xc=1+x;LL yc=1+y;
118 LL ap1=(long long )(xc)*(long long)x/2;
119 LL ap2=(long long)(yc)*(long long)y/2;
120 ap2-=sum1;
121 ap1-=sum2;
122 ap2-=ap1;
123 for(j=1; j<bt; j++)
124 {
125 if(flag[j]>=x+1&&flag[j]<=y)
126 {
127 int cp=gcd(xy,ma[flag[j]]);
128 int cq=gcd(xy,flag[j]);
129 if(cq==1)
130 ap2-=flag[j];
131 if(cp==1)
132 ap2+=ma[flag[j]];
133 }
134 }
135 printf("%lld\n",ap2);
136 }
137 else
138 {
139 scanf("%d %d",&x,&t);
140 if(my[x]==0)
141 {my[x]=1;flag[bt]=x;bt++;}
142 ma[x]=t;
143 }
144 }
145 }
146 return 0;
147 }
148 int gcd(int n,int m)
149 {
150 if(m==0)
151 return n;
152 else if(n%m==0)
153 return m;
154 else return gcd(m,n%m);
155 }
 

Sum(hdu4407)的更多相关文章

  1. hdu4407 Sum 容斥原理

    XXX is puzzled with the question below: 1, 2, 3, ..., n (1<=n<=400000) are placed in a line. T ...

  2. LeetCode - Two Sum

    Two Sum 題目連結 官網題目說明: 解法: 從給定的一組值內找出第一組兩數相加剛好等於給定的目標值,暴力解很簡單(只會這樣= =),兩個迴圈,只要找到相加的值就跳出. /// <summa ...

  3. Leetcode 笔记 113 - Path Sum II

    题目链接:Path Sum II | LeetCode OJ Given a binary tree and a sum, find all root-to-leaf paths where each ...

  4. Leetcode 笔记 112 - Path Sum

    题目链接:Path Sum | LeetCode OJ Given a binary tree and a sum, determine if the tree has a root-to-leaf ...

  5. POJ 2739. Sum of Consecutive Prime Numbers

    Sum of Consecutive Prime Numbers Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20050 ...

  6. BZOJ 3944 Sum

    题目链接:Sum 嗯--不要在意--我发这篇博客只是为了保存一下杜教筛的板子的-- 你说你不会杜教筛?有一篇博客写的很好,看完应该就会了-- 这道题就是杜教筛板子题,也没什么好讲的-- 下面贴代码(不 ...

  7. [LeetCode] Path Sum III 二叉树的路径和之三

    You are given a binary tree in which each node contains an integer value. Find the number of paths t ...

  8. [LeetCode] Partition Equal Subset Sum 相同子集和分割

    Given a non-empty array containing only positive integers, find if the array can be partitioned into ...

  9. [LeetCode] Split Array Largest Sum 分割数组的最大值

    Given an array which consists of non-negative integers and an integer m, you can split the array int ...

随机推荐

  1. react native 导航器 Navigator 简单的例子

    最近学习react native 是在为全栈工程师而努力,看网上把react native说的各种好,忍不住学习了一把.总体感觉还可以,特别是可以开发android和ios这点非常厉害,刚开始入门需要 ...

  2. C语言中的各种字符串输入方法

    C语言从stdin读取一行字符串的几种方法 gets gets函数的头文件是<stdio.h>,原型如下: char *gets(char *s); gets从stdin中读入一行内容到s ...

  3. 用usb线配置直流电机驱动器不能配置成功

    原因可能是因为usb线的问题 换了三条usb线. 这三条都是通的,用万用表测试都是通的,但是进行电机配置的时候不行. 猜测原因可能是三条usb线的芯材质不同导致压降不同,使得通信故障.

  4. 【Other】逻辑分析仪的使用(UART、SPI)

    首先上一张接线示意图 上方是UART的接线方式,下方则是SPI的 事实上,这样接就能收到信号了 如果是SPI,要设定自己为主机,UART则没有这个问题 下面来说明逻辑分析仪的界面设定 设定介绍完了 下 ...

  5. Linux学习 - 条件判断

    一.判断格式 test -e /root/install.log 或 [ -e /root/install.log ] 使用echo $?查看是否正确,当返回0时表示返回正确 1 按照文件类型进行判断 ...

  6. Linux基础命令---enable开启shell命令

    enable enable指令用来关闭或者激活shell内部命令.此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.Fedora. 1.语法       enable [-a]   ...

  7. 使用MySQL的SELECT INTO OUTFILE ,Load data file,Mysql 大量数据快速导入导出

    使用MySQL的SELECT INTO OUTFILE .Load data file LOAD DATA INFILE语句从一个文本文件中以很高的速度读入一个表中.当用户一前一后地使用SELECT ...

  8. 用运oracel中的伪列rownum分页

    在实际应用中我们经常碰到这样的问题,比如一张表比较大,我们只要其中的查看其中的前几条数据,或者对分页处理数据.在这些情况下我们都需要用到rownum.因此我们要理解rownum的原理和使用方法. Or ...

  9. linux下把一个用户从某个组中删除,而不删除用户

    查看当前用户/登录用户 基本语法 whoami / who am I 用户组 介绍 类似于角色,系统可以对有共性的多个用户进行统一的管理. 新增组 语法 groupadd 组名 案例演示 添加test ...

  10. Docker的常用命令总结

    一.普通指令 启动 Docker sudo systemctl start docker 停止 Docker sudo systemctl stop docker 普通重启 Docker sudo s ...