1. 程式人生 > >基礎算法學習以及$STL$的使用

基礎算法學習以及$STL$的使用

tor pop 小根堆 () lin 從大到小 eat 大根堆 比較

1.優先隊列

(1)大根堆(小頂堆)

priority_queue<int,vector<int>,greater<int> >q;

(2)小根堆(大頂堆)

priority_queue<int, vector<int>, less<int> >q;
//或者
priority_queue<int>q;

用法

q.push(x);//入隊列

q.pop();//堆頂值

q.back();//隊尾值

q.pop();//出隊列

q.empty();//返回q是否為空,空則返回1,否則返回0

q.size();//返回q裏元素個數

2.排序

(1)快排(STL萬歲!\(QwQ\))

sort(a+1,a+n+1);//a數組1~n從小到大排序

(2)結構體排序

//定義
struct node{
int x,y;
};
node a[maxn];
//先從小到大按x值排序,再從大到小按y值排序
bool cmp(node s1,node s2){
if(s1.x!=s2.x)return s1.x<s2.x;
return s1.y>s2.y;
}
//主函數內
sort(a+1,a+n+1,cmp);

(3)結構體內重載運算符

struct node
{
    int x,y;
    bool operator < (const node & a) const
    {
        return x<a.x;
    }
};

(4)歸並排序

#include<cstdio>
#include<cmath>
#include<set>
#include<stack>
#include<queue>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define _for(i,a,b) for(int i=a;i<=b;i++)
#define maxn 500005
using namespace std;
typedef long long ll;
int t[100005],ans=0;
int n,a[100005];

int read(){
    int f=1,ans=0;
    char c=getchar();
    while(!isdigit(c)){
        if(c=='-')f=-1;
        c=getchar();
    }
    while(isdigit(c)){
        ans=ans*10+c-'0';
        c=getchar();
    }
    return f*ans;
}

void gb(int a[],int l,int r){ 
    if(l==r)
    return;
    int mid=(l+r)/2;
    gb(a,l,mid); 
    gb(a,mid+1,r);
    int i=l,j=mid+1,p=l;
    while(i<=mid&&j<=r){
        if(a[i]>a[j]){
            t[p++]=a[j++];
            ans+=mid-i+1;        }
        else
        t[p++]=a[i++];
    }
    while(i<=mid)
    t[p++]=a[i++];
    while(j<=r)
    t[p++]=a[j++];
    for(i=l;i<=r;i++)
    a[i]=t[i];
}
int main(){

    cin>>n;
    for(int i=1;i<=n;i++)
    cin>>a[i];
    gb(a,1,n);
    cout<<ans<<endl;
    return 0;
}

(5)手寫快排

int a[101];

void hand_write_quick_sort(int l,int r)
{
    if(l>=r) return;
    else
    {
        int i=l;
        int j=r;
        int top=a[i];
        //a[i]即為我們選擇的“點”,用於分割
       //(我們用的是這個點的值,而不是位置。)
        while(i<j)
        {
         while(top<=a[j] && (i<j)) j--;
         //a[j]比top大,則換下一個進行比較
         a[i]=a[j];//"點"的位置變為a[j]
         while(a[i]<=top && (i<j)) i++;
         //a[i]比top小,則換下一個進行比較
         a[j]=a[i];//"點"的位置變為a[i]
         }        //小的往前去,大的往後退。
        a[i]=top;
        hand_write_quick_sort(l,i-1);
        hand_write_quick_sort(i+1,r);
    }
}

//l~r中第k大的數(分治)
LL get(int l, int r, int k)
{
    if (l == r) return a[k];
    int u = l + rand() % (r-l+1);
    LL v = a[u];
    swap(a[l], a[u]);

    int i = l, j = r;
    while (i < j)
    {
        while (i < j && a[j] >= v) j--;
        if (i < j) { a[i] = a[j], i++; }
        while (i < j && a[i] < v) i++;
        if (i < j) { a[j] = a[i], j--; }
    }
    a[i] = v;

    while (i < (l+r)/2 && a[i] == a[i+1]) i++;

    if (k < i) return get(l, i-1, k);
    else if (k > i) return get(i+1, r, k);
    else return v; 
}

基礎算法學習以及$STL$的使用