目录
队列安排(双向链表)
思路:
1.首先,先建一个结构体,分left和right,然后一开始只有1号,要设一个边界,表的最左边是0,最右边是100010(因为数据大不过100010)。
2.接着对于每次插入,有左和右种情况,如A,C中插入B,就要改A的right,将A.right的C改为B,就要改C.left的A改为B,那新来的B呢?它的左右邻居就要赋值(B.left=A,B.right=C)。
3.对于每次删除,就要更新被删除者的左右两边数据,如A,B,C删除B,就要改B.left的右边(A.right)为C,就要改B.right的左边(C.left)为A。
4.最后输出时先从bib.right开始判断(一开始bib为0),如果bib.right是有数据的,那么就输出并把下一个的bib跟新为bib.right以准备判断。如果bib.right是100010,也就是边界,说明没有后路了就退出。
数组:
// Problem: P1160 队列安排
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1160
// Memory Limit: 125 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<map>
using namespace std;
typedef long long ll;
const int N = 200010;
int l[N],r[N];
bool st[N];
int n,m;
void init(){
r[0]=1;
l[1]=0;
r[0]=1;
}
void add_left(int k,int x){
r[l[k]]=x;
l[x]=l[k];
r[x]=k;
l[k]=x;
}
void add_right(int k,int x){
l[r[k]]=x;
r[x]=r[k];
l[x]=k;
r[k]=x;
}
void s(){
cin>>n;
init();
memset(st,false,N);
for(int i=2;i<=n;i++){
int k,op;
cin>>k>>op;
if(op==0){
add_left(k,i);
}
else{
add_right(k,i);
}
}
cin>>m;
for(int i=1;i<=m;i++){
int p;
cin>>p;
st[p]=1;
}
for(int i=r[0];1;i=r[i]){
if(st[i]==0) cout<<i<<' ';
if(r[i]==0) break;
}
}
int main(){
int T=1;
//cin>>T;
while(T--){
s();
}
return 0;
}
list容器
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+5;
int main(){
int n,m;
cin>>n;
vector<list<int>::iterator> v(n);
list<int> lis;
lis.push_front(0);
v[0]=lis.begin();
for(int i=1;i<n;i++){
int k,p;
cin>>k>>p;
k--;
if(p==1){
auto nxt=next(v[k]);
v[i]=lis.insert(nxt,i); //在next位置插i元素,之后的向后移
}
else{
v[i]=lis.insert(v[k],i);
}
}
cin>>m;
vector<bool> ve(n);
while(m--){
int x;
cin>>x;
x--;
if(ve[x]){
continue;
}
ve[x]=true;
lis.erase(v[x]);
}
for(int x:lis){
cout<<x+1<<" "[x==lis.back()];
}
return 0;
}
表达式求值(栈/思维)
代码:
// Problem: P1981 [NOIP2013 普及组] 表达式求值
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1981
// Memory Limit: 125 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+5;
const int mod=10000;
int main(){
stack<int> x; //先进后出
int a,b;
char c;
cin>>a;
a%=mod; //不加会wa
x.push(a);
while(cin>>c>>b){
if(c=='*'){
int t=x.top();
x.pop(); //此时对头为a,所以要删除,以便后面再多加一遍
x.push(t*b%mod);
}
else{
x.push(b); //队头会变成b
}
}
int res=0;
while(x.size()){
res+=x.top();
res%=mod;
x.pop();
}
cout<<res<<"\n";
return 0;
}
求m区间内的最小值(单调队列)
数组:
// Problem: P1440 求m区间内的最小值
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1440
// Memory Limit: 125 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
const int N = 2000010;
int a[N],q[N];
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
cout<<0<<"\n";
int hh=0,tt=-1;
for(int i=1;i<n;i++){ //ai之前m个数,不算ai
if(hh<=tt&&i-q[hh]+1>m){
hh++; //队头出队
}
while(hh<=tt&&a[i]<=a[q[tt]]){
tt--; //后面的数小于队尾,队尾出队
}
q[++tt]=i;
cout<<a[q[hh]]<<"\n";
}
return 0;
}
deque
// Problem: P1440 求m区间内的最小值
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1440
// Memory Limit: 125 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
#include<cstdio>
#include<deque>
using namespace std;
const int N=2e6+6;
int n,m;
int a[N],ans[N];
deque<int> de;
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
while(de.size()!=0&&de.front()<i-m){
de.pop_front();
}
if(de.size()==0) printf("0\n");
else printf("%d\n",a[de.front()]);
while(de.size()!=0&&a[de.back()]>=a[i]) {
de.pop_back();
}
de.push_back(i);
}
return 0;
}
滑动窗口 /【模板】单调队列
数组:
// Problem: P1440 求m区间内的最小值
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1440
// Memory Limit: 125 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
const int N = 2000010;
int a[N],q[N];
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
int hh=0,tt=-1;
for(int i=1;i<=n;i++){
if(hh<=tt&&i-q[hh]+1>m){
hh++;
}
while(hh<=tt&&a[i]<=a[q[tt]]){
tt--;
}
q[++tt]=i;
if(i>=m) cout<<a[q[hh]]<<' ';
}
cout<<"\n";
hh=0,tt=-1;
for(int i=1;i<=n;i++){
if(hh<=tt&&i-q[hh]+1>m){
hh++;
}
while(hh<=tt&&a[i]>=a[q[tt]]){
tt--;
}
q[++tt]=i;
if(i>=m) cout<<a[q[hh]]<<' ';
}
cout<<"\n";
return 0;
}
deque
#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;
int main(){
int n, k;
int a[N];
cin >> n >> k;
for (int i = 1; i <= n; i ++ ) {
cin >> a[i];
}
deque<int> q;
for(int i = 1; i <= n; i++) {
while(q.size() && q.back() > a[i])
q.pop_back();
q.push_back(a[i]);
if(i - k >= 1 && q.front() == a[i - k])
q.pop_front();
if(i >= k)
cout << q.front() <<" ";
}
q.clear();
cout << endl;
for(int i = 1; i <= n; i++) {
while(q.size() && q.back() < a[i]) q.pop_back();
q.push_back(a[i]);
if(i - k >= 1 && a[i - k] == q.front()) q.pop_front();
if(i >= k) cout << q.front() << " ";
}
return 0;
}
机器翻译 (队列)
// Problem: P1540 [NOIP2010 提高组] 机器翻译
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1540
// Memory Limit: 125 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
const int N = 200010;
bool st[N];
int main(){
int m,n;
cin>>m>>n;
memset(st,false,N);
int a[N];
for(int i=0;i<n;i++){
cin>>a[i];
}
ll res=0;
queue<int> q;
for(int i=0;i<m;i++){
if(!st[a[i]]){
q.push(a[i]);
st[a[i]]=1;
res++;
}
}
for(int i=m;i<n;i++){
if(q.size()>m){
st[q.front()]=0;
q.pop();
}
if(!st[a[i]]){
q.push(a[i]);
st[a[i]]=1;
res++;
}
}
cout<<res<<"\n";
return 0;
}
小组队列(队列)
// Problem: P2776 [SDOI2007] 小组队列
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2776
// Memory Limit: 125 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const int N = 200010;
int main(){
int n,m;
cin>>n>>m;
int a[N];
queue<int> zu,q[301];
for(int i=0;i<n;i++){
cin>>a[i];
}
int t;
cin>>t;
while(t--){
string op;
cin>>op;
if(op=="push"){
int x;
cin>>x;
if(q[a[x]].empty()){ //q数组里面的
zu.push(a[x]);
}
q[a[x]].push(x); //a[x]后面加上x
}
else{
cout<<q[zu.front()].front()<<"\n"; //
q[zu.front()].pop(); //移除
if(q[zu.front()].empty()){
zu.pop();
}
}
}
return 0;
}
堆
// Problem: P3378 【模板】堆
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3378
// Memory Limit: 512 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int N = 2000010;
int h[N],ph[N],hp[N],cnt;
void heap_swap(int a,int b){
swap(ph[hp[a]],ph[hp[b]]);
swap(hp[a],hp[b]);
swap(h[a],h[b]);
}
void up(int u){
while(u/2&&h[u]<h[u/2]){
heap_swap(u,u/2);
u>>=1;
}
}
void down(int u){
int t=u;
if(u*2<=cnt&&h[u*2]<h[t]) t=u*2;
if(u*2+1<=cnt&&h[u*2+1]<h[t]) t=u*2+1;
if(u!=t){
heap_swap(u,t);
down(t);
}
}
void s(){
int n,m=0;
cin>>n;
while(n--){
int op;
cin>>op;
if(op==1){
ll x;
cin>>x;
cnt++;
m++;
ph[m]=cnt,hp[cnt]=m;
h[cnt]=x;
up(cnt);
}
else if(op==2){
cout<<h[1]<<"\n";
}
else if(op==3){
heap_swap(1,cnt);
cnt--;
down(1);
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T=1;
//cin>>T;
while(T--){
s();
}
return 0;
}
切蛋糕(单调队列)
// Problem: P1714 切蛋糕
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1714
// Memory Limit: 128 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e5+5;
int main(){
int n,m;
cin>>n>>m;
int a[N],sum[N];
for(int i=0;i<N;i++){
sum[i]=0;
}
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
sum[i]=sum[i-1]+a[i];
}
deque<int> de;
de.push_back(0);
int ans=-0x3f3f3f3f;
for(int i=1;i<=n;i++){
while(de.front()+m<i){
de.pop_front();
}
ans=max(ans,sum[i]-sum[de.front()]);
while(!de.empty()&&sum[de.back()]>sum[i]){
de.pop_back();
}
de.push_back(i);
}
cout<<ans<<"\n";
return 0;
}