(未完待续。。。)
更新队列:二分(lower_bound&upper_bound)完善,vector,deque,set,bitset以及一些神奇函数
本文同步更新于我的luogu blog
前言:
STL是个好东西,可以帮助我们较快懒的构建程序。
虽然这玩意儿常数大
但在时间复杂度正确的情况下,一般不会有人xian de dan teng去卡STL的。
在本蒟蒻会的前提下整理的,可能不全
目录:
队列&优先队列
二分(lower_bound&upper_bound)
正文
这玩意儿应该挺好理解,大佬们把它优化的很好了,一般排序就用它就ok
输入:
10
5465 12 54 6 21 54 315 1 0 1
#include<cstdio> #include<algorithm>//sort所在头文件 using namespace std;//sort const int N=10005; int n,a[N]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } sort(a+1,a+n+1); /* a:排序数组名称 1:起始下标 n:数组长度 */ for(int i=1;i<=n;i++) { printf("%d ",a[i]); } return 0; }
输出
0 1 1 6 12 21 54 54 315 5465
sort排序一般默认为从小到大排,若想要从大到小排,我们可以重定义其中的比较函数,代码如下:
#include<bits/stdc++.h> using namespace std; const int N=10005; int n,a[N]; bool cmp(int a,int b) { return a>b; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } sort(a+1,a+n+1,cmp); /* cmp:比较函数 */ for(int i=1;i<=n;i++) { printf("%d ",a[i]); } return 0; }
输出:
5465 315 54 54 21 12 6 1 1 0
当然,我们也可以根据实际需要对cmp函数做出相应更改:
如,对结构体排序:
#include<cstdio> #include<algorithm>//sort所在头文件 using namespace std;//sort const int N=10005; int n; struct qwq{ int x,y; }; qwq a[N],b[N]; bool cmp(const qwq &a,const qwq &b) { return a.x==b.x?a.y<b.y:a.x>b.x; //以结构体中x为第一关键字降序排列,y升序排列 /*等价于 if(a.x==b.x)return a.y<b.y; else return a.x>b.y; */ } bool com(const qwq &a,const qwq &b) { return a.y==b.y?a.x<b.x:a.y<b.y; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&a[i].x,&a[i].y); b[i].x=a[i].x,b[i].y=a[i].y; } sort(a+1,a+n+1,cmp); sort(b+1,b+n+1,com); /* com,cmp:比较函数 */ printf("\n"); for(int i=1;i<=n;i++) { printf("%d %d\n",a[i].x,a[i].y); } printf("\n"); for(int i=1;i<=n;i++) { printf("%d %d\n",b[i].x,b[i].y); } return 0; } /*输入: 10 3 5 9 8 4 6 1 0 3 8 6 1 2 2 8 5 1 9 7 2 a数组输出: 9 8 8 5 7 2 6 1 4 6 3 5 3 8 2 2 1 0 1 9 b数组输出: 1 0 6 1 2 2 7 2 3 5 8 5 4 6 3 8 9 8 1 9 */
队列&优先队列
#include<queue>
啊,这可真是个好东西苍蝇搓手ing
queue
queue 模板类的定义在queue头文件中。
queue 模板类需要两个模板参数,一个是元素类型,一个容器类型,元素类型是必要的,容器类型是可选的,默认为deque 类型。
queue兹磁的常见操作:
#include<iostream> #include<queue> using namespace std; int n,x; queue <int>q; int main() { cin>>n; for(int i=1;i<=n;i++) { cin>>x; q.push(x);//入队,将x接到队列的末端 int tail=q.back();//访问队尾元素,即最后被压入队列的元素 cout<<tail<<endl; } while(!q.empty())//判断队列空,当队列空时,返回true { cout<<q.size()<<endl;//访问队列中的元素个数 int TOP=q.front();//访问队首元素 cout<<TOP<<endl; q.pop();//出队,弹出队列的第一个元素,并不会返回被弹出元素的值 } return 0; }
priority_queue
优先队列和队列有神马不同呢?
优先队列不同于队列,队列是先进先出,优先队列是大数先出(默认)
#include<iostream> #include<queue> using namespace std; int n,x; priority_queue<int>q; int main() { /* 输入: 10 1 3 5 2 0 4 9 7 8 10 */ cin>>n; for(int i=1;i<=n;i++) { cin>>x; q.push(x); cout<<q.top()<<" "; } /* 输入时队头输出: 1 3 5 5 5 5 9 9 9 10 */ cout<<endl; while(!q.empty()) { cout<<q.top()<<" "; q.pop(); } /* 出队顺序: 10 9 8 7 5 4 3 2 1 0 */ return 0; }
如果宁仔细看看就会发现这个B优先队列它其实是个大根堆(默认)
那我想用优先队列实现dij堆优该咋办呢?
手写堆
重载比较函数
要小根堆的话,可以
1.重载operator
2.c++友情提供的greater<>
懒得放代码了
友情赠送一份堆优dij代码
1 #include<bits/stdc++.h> 2 #include<queue> 3 #define ll long long 4 #define fo(a,b,c) for(register int a=b;a<=c;a++) 5 #define fr(a,b,c) for(register int a=b;a>=c;a--) 6 7 using namespace std; 8 const int N=100005; 9 const int M=500005; 10 const int inf=INT_MAX; 11 int n,m,s; 12 int vi,ui,wi; 13 int dis[N]; 14 bool v[N]; 15 inline int read() 16 { 17 int x=0,f=1; 18 char ch=‘ ‘; 19 while(ch<‘0‘||ch>‘9‘) 20 { 21 if(ch==‘-‘)f=-1; 22 ch=getchar(); 23 } 24 while(ch>=‘0‘&&ch<=‘9‘) 25 { 26 x=(x<<3)+(x<<1)+ch-‘0‘; 27 ch=getchar(); 28 } 29 return x*f; 30 } 31 inline void write(int x) 32 { 33 int y=10,len=1; 34 while(y<=x) 35 { 36 y*=10; 37 len++; 38 } 39 while(len--) 40 { 41 y/=10; 42 putchar(x/y+‘0‘); 43 x%=y; 44 } 45 } 46 int to[M],h[M],w[M],nx[M],cnt=0; 47 inline void add(int u,int v,int k) 48 { 49 to[++cnt]=v; 50 nx[cnt]=h[u]; 51 h[u]=cnt; 52 w[cnt]=k; 53 } 54 struct node{ 55 int dis,u; 56 bool operator <(const node& rsh)const{ 57 return rsh.dis<dis; 58 } 59 }; 60 priority_queue<node> q; 61 inline void dij() 62 { 63 fo(i,1,n)dis[i]=inf; 64 dis[s]=0; 65 q.push((node){0,s}); 66 while(!q.empty()) 67 { 68 node tmp=q.top(); 69 q.pop(); 70 int x=tmp.u,d=tmp.dis; 71 if(v[x])continue; 72 v[x]=1; 73 for(int i=h[x];i;i=nx[i]) 74 { 75 int y=to[i]; 76 if(dis[y]>dis[x]+w[i]) 77 { 78 dis[y]=dis[x]+w[i]; 79 if(!v[y]) 80 { 81 q.push((node){dis[y],y}); 82 } 83 } 84 } 85 } 86 } 87 int main() 88 { 89 memset(v,0,sizeof(v)); 90 n=read(),m=read(),s=read(); 91 fo(i,1,m) 92 { 93 ui=read(),vi=read(),wi=read(); 94 add(ui,vi,wi); 95 //add(vi,ui,wi); 96 } 97 dij(); 98 fo(i,1,n) 99 { 100 printf("%d ",dis[i]); 101 //write(dis[i]);putchar(‘ ‘); 102 } 103 return 0; 104 }
二分
lower_bound()和upper_bound()
咕咕咕
未完待续....
原文:https://www.cnblogs.com/Ln-YJin/p/11647466.html