@kaike
尽管我们手中空无一物,却能因此紧紧相连。
1.质数
(prime.pas/c/cpp)
【问题描述】
质数也叫素数,指除了1和它本身没有其他因子的整数。
质数是数论中很特殊的数,作用也很大,小x也在研究。
小x对小y说,你给我一个数字,我可以告诉你这个数字是不是质数。读题的你肯定很不屑小x的自大,这个还用说,只要学习OI的都会。
那么小x的问题就改为:给你一个区间[X,Y],问从X到Y有多少个质数。
【输入】
两个整数X和Y。保证 X<=Y。
【输出】
一个整数,表示X到Y有多少个质数。
【输入输出样例】
prime.in | prime.out |
2 11 | 5 |
【数据范围】
有部分数据保证 Y-X<=10000
100% 数据 X<=Y<=2147483647 (int 的最大值) Y-X<=1000000
想着说把所有素数全求出来,用前缀和,
后来数据太大,不可能以O(N*N)的计算量算出来
就去网上找了线性筛法。
后来又因为一个优化,应该吧 50000 以内的素数算出来,然后将 l-r 的合数筛掉
就这样只有40qaq,关键是40我还不会qaq
每次都觉得自己代码low爆了,别人代码都炒鸡好看怎么破
先附上40分
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 /* 2 by kaike 3 11/09/2016 4 */ 5 #include <iostream> 6 #include <cstdio> 7 using namespace std; 8 int prime[99999999]; 9 bool is_prime[99999999]; 10 int xx,yy; 11 int slove(int n) 12 { 13 int p = 0; 14 for(int i=0; i<=n;i++) 15 is_prime[i] = true; 16 is_prime[0] = is_prime[1] = false; 17 for(int i=2;i<=n;i++) 18 { 19 if(is_prime[i]) 20 { 21 prime[p++] = i; 22 for(int j=2*i; j<=n; j+=i) 23 is_prime[j] = false; 24 } 25 } 26 return p; 27 } 28 int main() 29 { 30 freopen("prime.in","r",stdin); 31 freopen("prime.out","w",stdout); 32 cin>>xx>>yy; 33 cout <<slove(yy)-slove(xx-1)<< endl; 34 fclose(stdin); 35 fclose(stdout); 36 return 0; 37 }
后来模仿jjh的代码过了60?
wtf?从两点调到了五点。我也不想说什么了
后来发现数据从int到了long long 成功过了。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 /* 2 by kaike 3 11/10/2016 4 */ 5 #include<iostream> 6 #include<cstdio> 7 #include<cmath> 8 #include<algorithm> 9 #include<iomanip> 10 #include<string> 11 #include<cstring> 12 #include<queue> 13 using namespace std; 14 #define FILE "prime" 15 const int MAXN=1000005; 16 const int LIM=50000; 17 const int oo=2147483647; 18 int x,y; 19 int p[MAXN],cot=0,ans=0; 20 bool vis[MAXN]; 21 void init() 22 { 23 cin>>x>>y; 24 for(long long i=2;i<=LIM;i++) 25 { 26 if(!vis[i]) p[++cot]=i; 27 for(long long j=1;j<=cot;j++) 28 { 29 if(i*p[j]>LIM) break; 30 vis[i*p[j]]=1; 31 if(i%p[j]!=0) break; 32 } 33 } 34 } 35 void work() 36 { 37 memset(vis,0,sizeof(vis)); 38 for(long long i=1;i<=cot;i++) 39 for(long long j=x/p[i];j<=oo;j++) 40 { 41 if(j*p[i]>y) break; 42 if(j*p[i]<x) continue; 43 if(j>1) 44 { 45 if(!vis[j*p[i]-x]) ans++; 46 vis[j*p[i]-x]=1; 47 } 48 } 49 if(x==1) ans++; 50 cout<<y-x+1-ans<<endl; 51 } 52 int main() 53 { 54 freopen(FILE".in","r",stdin); 55 freopen(FILE".out","w",stdout); 56 init(); 57 work(); 58 return 0; 59 }
2.飞天
(sky.pas/c/cpp)
【问题描述】
小x和他的小伙伴们创作了一个舞蹈——飞天。
这个舞蹈由N个小朋友一起来完成,编号分别为[1..N]。每位小朋友都被威亚吊着飞在天空中,每个人的高度为H[i],做着各种高难度动作。
小x作为导演,又有了新的想法,他把舞蹈分为M大部分。每部分只挑选编号连续的某些小朋友,升到相同的高度,做相应的表演。等本部分表演结束,小朋友的高度会自动恢复到原来的高度。
但是,现在每次调整高度难坏了小x,并且每位选手调整的高度增加或减少1,小x就要花费单位为1的能量,小x就想知道,怎么安排调整高度,能让自己消耗的能量最少。
【输入】
第一行为两个正整数n、m。
第二行共n个非负整数,表示第i位小朋友的高度h[i]。
接下来m行每行2个整数Li、Ri(Li≤Ri)。 表示要调整编号为[Li,Ri]的高度
【输出】
一个整数,表示调整高度的最小能量消耗。
【输入输出样例1】
sky.in | sky.out |
6 4 4 1 2 13 0 9 1 5 2 6 3 4 2 2 | 48 |
【样例解释】
第一次调整编号为1..5的小朋友,如果把高度都调整为2,那么消耗能量为2+1+0+11+2=16。这个是最小的。
第二次调整编号为2..6的小朋友,能量值消耗最小为21。
第三次消耗为11。第四次消耗为0。
总消耗为48。
【数据范围】
对于50%的数据 n≤500,m≤1000;
对于80%的数据 n≤1000,m≤100000;
对于100%的数据n≤1000,m≤200000;
答案小于2^64。
我能说我真没想到中位数么,第一感觉woc它咋知道这数的,第二感觉这肯定是二分找数对没错
于是华丽丽的交上去
20
don't want to say what。
先来个70,没什么可说的注意long long ,找中位数而已。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 /* 2 by kaike 3 11/10/2016 4 */ 5 #include<iostream> 6 #include<algorithm> 7 #include<iomanip> 8 #include<cstring> 9 #include<string> 10 #include<cmath> 11 #include<queue> 12 using namespace std; 13 #define FILE "sky" 14 int n,m,h[1100],x,y,b[1100]; 15 long long ans=0; 16 void init() 17 { 18 cin>>n>>m; 19 for(int i=1;i<=n;i++) 20 cin>>h[i]; 21 } 22 void work() 23 { 24 for(int i=1;i<=m;i++) 25 { 26 cin>>x>>y; 27 if(x==y) continue; 28 for(int j=1;j<=y-x+1;j++) 29 b[j]=h[x+j-1]; 30 sort(b+1,b+y-x+2); 31 int t; 32 if((y-x+1)%2==0) t=b[(y-x+1)/2]; 33 else t=b[(y-x+1)/2+1]; 34 for(int j=x;j<=y;j++) 35 ans+=abs(h[j]-t); 36 } 37 cout<<ans<<endl; 38 } 39 int main() 40 { 41 freopen(FILE".in","r",stdin); 42 freopen(FILE".out","w",stdout); 43 init(); 44 work(); 45 return 0; 46 }
1.树
(tree.pas/c/cpp)
【问题描述】
Fanvree很聪明,解决难题时他总会把问题简单化。
例如,他就整天喜欢把图转化为树。但是他不会缩环,那他怎么转化呢?
这是一个有n个点m条双向边的图,Fanvree会选定一个节点,然后删掉这个节点和这个点连出去的边,如果变成了一棵树,那么这个节点便是可行的,什么是树呢?树也即无简单环的无向连通图。
现在你需要告诉Fanvree可能的节点是什么。
【输入】
第一行两个正整数 n,m,表示有 n 个点 m 条边。保证 n≥2。
接下来 m 行,每行两个整数 v,u,表示 v 和 u 之间有一条无向边 1≤v,u≤n。保证 没有重边和自环。
【输出】
第一行一个正整数 ns,表示这个图中有 ns 个结点可选。
接下来一行,共 ns 个整数,每个整数表示一个可选结点的编号。请按编号从小 到大的顺序输出。
数据保证图中至少存在一个可选的结点。
【输入输出样例1】
tree.in | tree.out |
6 6 1 2 1 3 2 4 2 5 4 6 5 6 | 3 4 5 6 |
【数据范围】
对于40%的数据,n,m<=1000 另存在10%的数据,m=n-1
另存在20%的数据,m=n
对于100%的数据,n,m<=100000
这题就是找割点,在把可以构成环的删掉...不会环...割点还好吧...