上一篇详见https://blog.csdn.net/mrcrack/article/details/61625530
因博客字数限制,只好再开一篇。2019-4-10
P1177 【模板】快速排序
P3366 【模板】最小生成树
P3367 【模板】并查集
P3371 【模板】单源最短路径(弱化版)
P3383 【模板】线性筛素数
//P1908 逆序对
//在线测评地址https://www.luogu.org/problemnew/show/P1908
//快排+离散化+树状数组
//逆序对个数49999+49998+...+1 个
//(49999+1)*49999/2=25000*49999=25000*50000=1.25*10^10
//int溢出,统计数量时,需采用long long
//for(i=1;i<=n;i++)b[a[i].i]=i;//理解如下
//101 103 102 105
//1 2 3 4
//排序后
//101 102 103 105
//1 3 2 4
//离散化后
//1 2 3 4
//b[1] b[3] b[2] b[4]
//即
//1 3 2 4
//1 2 3 4
//样例通过,提交40分,测试点6,10-20WA.2019-5-7
//改成cnt+=i-sum(b[i]);//此处写成cnt+=b[i]-sum(b[i]);
//提交40分,测试点6,10-20WA.
//翻看https://www.luogu.org/problemnew/solution/P1908
//作者: 学无止境 更新时间: 2018-11-03 08:37 在Ta的博客查看
//摘抄如下:
//Q3: 相等的元素是否会导致求解错误?每一个数(不管是否相等)对应的新数都不同诶?
//修改,提交AC。2019-5-7
#include
#include
#include
#define LL long long
#define maxn 500100
using namespace std;
int n,b[maxn],c[maxn];
LL cnt=0;
struct node{
int i,v;
}a[maxn];
int cmp(node a,node b){
return a.v==b.v?a.i
int lowbit(int x){
return x&-x;
}
void add(int x,int delta){
while(x<=n){
c[x]+=delta;
x+=lowbit(x);
}
}
int sum(int x){
int ans=0;
while(x>0){
ans+=c[x];
x-=lowbit(x);
}
return ans;
}
int main(){
int i;
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",&a[i].v),a[i].i=i;
sort(a+1,a+1+n,cmp);
for(i=1;i<=n;i++)b[a[i].i]=i;
memset(c,0,sizeof(c));
for(i=1;i<=n;i++){
add(b[i],1);
cnt+=i-sum(b[i]);//此处写成cnt+=b[i]-sum(b[i]);
}
printf("%lld\n",cnt);
return 0;
}
简单数学
1.//P1865 A % B Problem
//在线测评地址https://www.luogu.org/problemnew/show/P1865
//质数 素数 线性筛法,掌握,还是要多模拟1-100的素数 筛选
//多开了一个数组f[i]用来统计到达i位置的素数个数。明显程序效率高了很多。
//上述改进,是查看他人代码习得的,有收获。2019-4-10
//以下为AC代码。
#include
#include
#define maxn 1000100
int prime[maxn/10],not_prime[maxn],f[maxn],cnt=0;
int n,m;
void linear_shaker(int x){
int i,j;
memset(not_prime,0,sizeof(not_prime)),memset(f,0,sizeof(f));
for(i=2;i<=x;i++){
if(!not_prime[i])prime[++cnt]=i,f[i]=f[i-1]+1;
else f[i]=f[i-1];
for(j=1;prime[j]*i<=x;j++){
not_prime[prime[j]*i]=1;
if(i%prime[j]==0)break;
}
}
}
int main(){
int left,right;
scanf("%d%d",&n,&m);
linear_shaker(m);
while(n--){
scanf("%d%d",&left,&right);
if(1<=left&&right<=m){
printf("%d\n",f[right]-f[left-1]);
}else printf("Crossing the line\n");
}
return 0;
}