待办:
倍增
并查集
线段树合并
set
逆序对
树
动态开点
线段树
- 套用模版
#include<bits/stdc++.h>
using namespace std;
#define M 100005
#define ll long long
struct node{
int L,R,cnt,vis;
}tree[400005];
int a[M],b[M],c[M],f[M];
void build(int p,int l,int r){
tree[p].L=l,tree[p].R=r;
if(l==r) return;
int mid=tree[p].L+tree[p].R>>1;
build(2*p,l,mid);
build(2*p+1,mid+1,r);
}
void up(int p){
tree[p].cnt=2e9;
if(tree[2*p].vis) tree[p].cnt=tree[2*p].cnt;
if(tree[2*p+1].vis) tree[p].cnt=min(tree[p].cnt,tree[2*p+1].cnt);
tree[p].vis=(tree[2*p].vis||tree[2*p+1].vis);
}
void add(int p,int x,int a){
if(tree[p].L==tree[p].R){
tree[p].cnt+=a;
if(tree[p].cnt)tree[p].vis=1;
else tree[p].vis=0;
return;
}
int mid=tree[p].L+tree[p].R>>1;
if(x<=mid) add(2*p,x,a);
else add(2*p+1,x,a);
up(p);
}
int query(int p){
if(tree[p].L==tree[p].R) return tree[p].L;
if(tree[2*p+1].vis&&tree[2*p+1].cnt==1) return query(2*p+1);
else if(tree[2*p].vis&&tree[2*p].cnt==1) return query(2*p);
return -1;
}
signed main(){
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
b[i]=a[i];
}
sort(b+1,b+n+1);
int len=unique(b+1,b+n+1)-b;
for(int i=1;i<=n;i++) c[i]=lower_bound(b+1,b+len+1,a[i])-b,f[c[i]]=a[i];
build(1,1,100000);
for(int i=1;i<=k;i++) add(1,c[i],1);
for(int i=1;i<=n-k+1;i++){
int ans=query(1);
if(ans==-1)puts("Nothing");
else cout<<f[ans]<<endl;
add(1,c[i],-1);
if(i-k<=n) add(1,c[i+k],1);
}
return 0;
}
并查集(待学)
倍增
-
思想
-
画图
分块
-
以前学习笔记
-
很好用