NOIP模板複習——基礎演算法
阿新 • • 發佈:2018-12-30
二分
求滿足條件的最小值
while(l<r)
{
int mid=(l+r)>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
求滿足條件的最大值
while(l<r)
{
int mid=(l+r+1)>>1;
if(check(mid)) l=mid;
else r=mid-1;
}
實數域上的二分(可以用 ,也可以二分 次)
while(l+eps<r)
{
double mid=(l+r)/2;
if(check(mid)) r=mid;
else l=mid;
}
三分
求單峰函式最大值
while(r-l>= eps)
{
m1=l+(r-l)/3;
m2=r-(r-l)/3;
if(f(m2)-f(m1)>=eps) l=m1;
else r=m2;
}
求最小值和求最大值差不多,注意一下好點和壞點之前的關係就行了
逆序對
分治+歸併排序
long long merge(int l,int r,int mid)
{
long long ans=0;
int i,b1=0,c1=0,b2=1,c2=1;
for(i=l;i<=mid;++i) b[++b1]=a[i];
for(i=mid+1;i<=r;++i) c[++c1]=a[i];
for (i=l;i<=r;++i)
{
if(b1>=b2&&(c1+1==c2||b[b2]<=c[c2]))
a[i]=b[b2++];
else
{
a[i]=c[c2++];
ans+=b1-b2+1;
}
}
return ans;
}
long long solve(int l,int r)
{
if(l==r) return 0;
int mid=(l+r)>>1;
long long ans=0;
ans+=solve(l,mid);
ans+=solve(mid+1,r);
ans+=merge(l,r,mid);
return ans;
}
樹狀陣列(只貼最核心的三行,其他的都是樹狀陣列基本操作)
for(i=1;i<=n;++i)
{
scanf("%d",&x);
add(x,1);
ans+=i-sum(x);
}
進位制轉換
十進位制轉其他進位制( 為原十進位制數, 為要轉換的進位制)
int pos=0;
while(x!=0)
{
a[++pos]=x%n;
x/=n;
}
for(i=pos;i;--i)
{
if(a[i]>10) printf("%c",a[i]-10+'A');
else printf("%d",a[i]);
}
其他進位制轉十進位制( 陣列存的是原來的進位制數,下標從 開始, 為原來的進位制, 是轉換後的十進位制數)
for(i=1;i<=l;++i)
{
if(a[i]>='0'&&a[i]<='9') s=a[i]-'0';
else s=a[i]-'A'+10;
x=x*n+s;
}
離散化
陣列是離散化後的陣列,起初所有的
sort(b+1,b+n+1);
int m=unique(b+1,b+n+1)-(b+1);
for(i=1;i<=n;++i)
a[i]=lower_bound(b+1,b+m+1,a[i])-b;
中位數
可以直接用 nth_element 實現
if(n&1)
{
nth_element(a+1,a+n/2+1,a+n+1);
return a[n/2+1];
}
else
{
double x;
nth_element(a+1,a+n/2,a+n+1),x=a[n/2];
nth_element(a+1,a+n/2+1,a+n+1),x+=a[n/2+1];
x/=2;
return x;
}