快排+树状数组+线段树+离散化+扫描线

快排1;

#include<bits/stdc++.h>
using namespace std;
int a[5] = { 5,1,2,4,3 };
int partition(int begin, int end) {
    int pivot = begin - 1;
    for (int i = begin; i <= end - 1; i++) if (a[i] < a[end]) swap(a[i], a[++pivot]);
    swap(a[++ pivot], a[end]);
    return pivot;
}
void quicksort(int begin, int end) {
    if (begin < end) {
        int pivot = partition(begin, end);
        quicksort(begin, pivot - 1);
        quicksort(pivot + 1, end);
    }
}
int main() {
    quicksort(0, 4);
    for (int i = 0; i < 5; i++)cout << a[i] << " ";
    return 0;
}

快排2:

#include<bits/stdc++.h>
using namespace std;
int a[]={0,0,5,1,7,6};
void q(int l,int r){
    if(l>=r)return ;
    int t=a[l+r>>1],i=l-1,j=r+1;
    while(i<j){
        do i++; while(a[i]<t);
        do j--; while(a[j]>t);
        if(i<j)swap(a[i],a[j]);
    }
    q(l,j);
    q(j+1,r);
}
int main(){
    q(1,5);
    for(int i=1;i<=5;i++)cout<<a[i]<<' ';
    return 0;
}

 

对于十字链表的储存:

#include<bits/stdc++.h>
using namespace std;
void add();
void creat(crosslist& a);
void init();
void print();
struct node {
    int i, j;
    int value;
    node* right, *down;
};
struct crosslist {
    int row, col;
    int tu;
    node* rhead, * dhead;
};
int m, n;
crosslist a;
void creat(crosslist& a) {
    for (int i = 0; i < a.tu; i++) {
        node* temp;
        cin >> temp->i >> temp->j >> temp->value;
        temp->right = temp->down = NULL;
        if (a.rhead[temp->i].right == NULL) {
            a.rhead[temp->i].right = temp;
        }
        else {
            node* p = a.rhead[i].right;
            while (p->right && p->right->j < temp->j) {
                p = p->right;
            }
            temp->right = p->right;
            p->right = temp;
        }//行插入成功!
        if (a.dhead[temp->j].down = NULL) {
            a.dhead[temp->j].down = temp;
        }
        else {
            node* p = a.dhead[temp->j].down;
            while (p->down && p->down->i < temp->i) {
                p = p->down;
            }
            temp->down = p->down;
            p->down = temp;
        }//列插入成功!
    }
}
void init() {
    a.rhead = a.dhead = NULL;
    cin >> a.row >> a.col >> a.tu;
    a.rhead = new node[n];
    a.dhead = new node[m];
    //初始化行和列的头
    for (int i = 0; i < n; i++) {
        a.rhead[i].down = NULL;
    }
    for (int i = 0; i < m; i++) {
        a.dhead[i].right = NULL;
    }
    creat(a);
}

 树状数组1:

#include<bits/stdc++.h>
using namespace std;
const int N = 2e6;
int m,a[N],n,x,y,k,temp;
struct node{
    int sum,l,r;
}t[N];
void build(int i,int l,int r){
    if(l==r){
        t[i].l=t[i].r=l;
        t[i].sum=a[l];
        return;
    }
    t[i].l=l,t[i].r=r;
    int mid=l+r>>1;
    build(2*i,l,mid);
    build(2*i+1,mid+1,r);
    t[i].sum=t[i*2].sum+t[i*2+1].sum;
}
void add(int i,int x,int k){//单点修改,x,+k
    if(t[i].l==t[i].r){
        t[i].sum+=k;
        return ;
    }
    int mid=t[i].l+t[i].r>>1;
    if(x<=mid){
        add(i*2,x,k);
    }else{
        add(i*2+1,x,k);
    }
    t[i].sum+=k;
}
int query(int i,int l,int r){//区间查询
    if(t[i].l>=l && t[i].r<=r)return t[i].sum;
    if(t[i].l>r||t[i].r<l)return 0;
    int s=0;
    s+=query(i*2,l,r);
    s+=query(i*2+1,l,r);
    return s;
}
int main(){
    cin.tie(0);
    cin.sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    build(1,1,n);
    for(int i=1;i<=m;i++){
        cin>>temp;
        if(temp==1){
            cin>>x>>k;
            add(1,x,k);
        }else{
            cin>>x>>y;
            cout<<query(1,x,y)<<endl;
        }
    }
    return 0;
}
View Code

树状数组2:

#include<bits/stdc++.h>
using namespace std;
const int N = 2e6;
int m,a[N],n,x,y,k,temp,res;
struct node{
    int sum,l,r;
}t[N];
void build(int i,int l,int r){
    if(l==r){
        t[i].l=t[i].r=l;
        t[i].sum=a[l];
        return;
    }
    t[i].l=l,t[i].r=r;
    int mid=l+r>>1;
    build(2*i,l,mid);
    build(2*i+1,mid+1,r);
}
void add(int i,int x,int y,int k){//区间修改,x,y,+k
    if(t[i].l>=x&&t[i].r<=y){
        t[i].sum+=k;
        return ;
    }
    if(t[i].l>y||t[i].r<x)return;
    add(i*2,x,y,k);
    add(i*2+1,x,y,k);
}
void query(int i,int x){//单点查询
    res+=t[i].sum;
    if(t[i].l==t[i].r)return;
    int mid=t[i].l+t[i].r>>1;
    if(x<=mid)query(i<<1,x);
    else query(i<<1|1,x);
}
int main(){
    cin.tie(0);
    cin.sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    build(1,1,n);
    for(int i=1;i<=m;i++){
        cin>>temp;
        if(temp==1){
            cin>>x>>y>>k;
            add(1,x,y,k);
        }else{
            cin>>x;
            res=0;
            query(1,x);
            cout<<res<<endl;
        }
    }
    return 0;
}
View Code

树状数组1和树状数组2的区间操作中,对于包含的直接出结果,不包含的直接返回,剩下的就是不全包含的,直接递归就完事了,不用费心想什么边界情况。

这哥俩的细微区别还在于初始化的时候。

线段树模板过不去,不知道为啥。

来点ST模板:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int a[N][21],l,r,n,m;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
int main(){
    n=read(),m=read();
    for(int i=1;i<=n;i++)a[i][0]=read();
    for(int j=1;j<21;j++){
        for(int i=1;i+(1<<j-1)<=n;i++){//注意边界!
            a[i][j]=max(a[i][j-1],a[i+(1<<j-1)][j-1]);
        }
    }//nlogn的预处理
    while(m--){
        l=read(),r=read();
        int k=log2(r-l+1);
        printf("%d\n",max(a[l][k],a[r-(1<<k)+1][k]));
    }
    return 0;
}
View Code

 离散化代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,a[100];
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    sort(a+1,a+1+n);
    int tot=unique(a+1,a+1+n)-a-1;
    for(int i=1;i<=tot;i++)cout<<a[i]<<' ';
    return 0;
}
//lld只能以十进制输入,lli可以以10、16、8进制输入
//scanf只要%x,%o即可控制进制
//cin需要hex,oct
View Code

 

posted @ 2022-10-17 19:43  _a_rk  阅读(49)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end