队列
优先队列
方法:
和队列操作基本相同:
top 访问队头元素 // 不同点
pop 弹出队头元素
empty 队列是否为空
size 返回队列内元素个数
push 插入元素到队尾 (并排序)
emplace 原地构造一个元素并插入队列
默认类型:
priority_queue<int> que; // 默认大顶推, 即从大到小
priority_queue<int, vector<int>, greater<int> > que1; // 小顶堆
priority_queue<int, vector<int>, less<int> > que2; // 大顶堆
自定义类型:
//方法1 运算符重载 <
struct node{
int x, y;
bool operator < (const node& a) const{
return x < a.x; //大顶堆
}
};
priority_queue<node> que3;
两个变量时可以直接使用pair<>;
pair排序时是先根据first,再根据second。
typedef pair<int, int> PII;
priority_queue<PII, vector<PII>, greater<PII> > heap; // 定义一个小根堆
双端队列
// 构造函数
deque<int> deq
// 增加函数
deq.push_front(x)//双端队列头部增加一个元素X
deq.push_back(x) //双端队列尾部增加一个元素x
// 删除函数
deq.pop_front() //删除双端队列中最前一个元素
deq.pop_back() // 删除双端队列中最后一个元素
deq.front(); //返回队头元素
deq.back(); // 返回队尾元素
deq.clear() //清空双端队列中元素
//判断函数
deq.empty() //向量是否为空,若true,则向量中无元素
//大小函数
deq.size() //返回向量中元素的个数
线段树
区间修改,查询l,r区间是否为从小到大顺序。
false按顺序, true不按顺序。
struct NO {
int l;
int r;
int maxn;
int mini;
bool flag;
};
struct SigmentT {
NO t[N * 4];
void Pushup(int p) {
t[p].flag = t[p << 1].flag | t[p << 1 | 1].flag;
t[p].maxn = t[p << 1 | 1].maxn;
t[p].mini = t[p << 1].mini;
if(t[p << 1 | 1].mini < t[p << 1].maxn) t[p].flag = 1;
}
void Build(int p , int l , int r) {
t[p].l = l; t[p].r = r;
if(l == r) {t[p].maxn = t[p].mini = a[l];return;}
int mid = (l + r) >> 1;
Build(p << 1 , l , mid); Build(p << 1 | 1, mid + 1 , r);
Pushup(p); return;
}
// p:根节点, l:左边界, r:右边界, d:要修改的值
void Updata(int p , int l , int r , int d) {
if(l <= t[p].l && r >= t[p].r) {
t[p].maxn = t[p].mini = d;
return;
}
int mid = (t[p].l + t[p].r) >> 1;
if(l <= mid) Updata(p << 1 , l , r , d);
if(r > mid) Updata(p << 1 | 1 , l , r , d);
Pushup(p);
}
// p:根节点, l:左区间, r:右区间
bool Query(int p , int l , int r) {
if(l <= t[p].l && r >= t[p].r) return t[p].flag;
int mid = (t[p].l + t[p].r) >> 1;
bool ans = 0;
if(l <= mid) ans |= Query(p << 1 , l , r);
if(r > mid) ans |= Query(p << 1 | 1 , l , r);
if(l <= mid && r > mid && t[p << 1 | 1].mini < t[p << 1].maxn && !ans) ans |= 1;
return ans;
}
}tr;
int main() {
//freopen("aa.in","r",stdin);
scanf("%d%d",&n,&q);
for(int i = 1; i <= n; i++)
scanf("%d",&a[i]);
tr.Build(1 , 1 , n);
for(int i = 1; i <= q; i++) {
int op,x,y; scanf("%d%d%d",&op,&x,&y);
if(op == 1) tr.Updata(1 , x , x , y);
else if(tr.Query(1 , x , y)) printf("No\n");
else printf("Yes\n");
}
}
区间修改,求区间最大值和区间最大值的数目
https://ac.nowcoder.com/acm/contest/9667/B
#define mm(a,x) memset(a,x,sizeof a)
#define mk make_pair
#define ll long long
#define pii pair<int,int>
#define inf 0x3f3f3f3f
#define lowbit(x) (x) & (-x)
const int N = 2e5 + 10;
int n,m;
int a[N];
struct Node{
int l,r;
int v,cnt;
}tr[N * 4];
int maxv,cnt;
void pushup(int u){
tr[u].v = max(tr[u << 1].v,tr[u << 1 | 1].v);
tr[u].cnt = 0;
if(tr[u].v == tr[u << 1].v) tr[u].cnt += tr[u << 1].cnt;
if(tr[u].v == tr[u << 1 | 1].v) tr[u].cnt += tr[u << 1 | 1].cnt;
}
void build(int u,int l,int r){
if(l == r) tr[u] = {l,r,a[l],1};
else{
tr[u] = {l,r};
int mid = l + r >> 1;
build(u << 1,l,mid);
build(u << 1 | 1,mid + 1,r);
pushup(u);
}
}
void query(int u,int l,int r){
if(tr[u].l >= l && tr[u].r <= r){
if(maxv == tr[u].v) cnt += tr[u].cnt;
if(maxv < tr[u].v){
maxv = tr[u].v;
cnt = tr[u].cnt;
}
return ;
}
int mid = (tr[u].l + tr[u].r) >> 1;
if(l <= mid) query(u << 1,l,r);
if(r > mid) query(u << 1 | 1,l,r);
}
void modify(int u,int x,int v){
if(tr[u].l == x && tr[u].r == x){
tr[u].cnt = 1;
tr[u].v = v;
}
else{
int mid = (tr[u].l + tr[u].r) >> 1;
if(x <= mid) modify(u << 1,x,v);
else modify(u << 1 | 1,x,v);
pushup(u);
}
}
int main() {
cin >> n >> m;
for(int i = 1; i <= n; i ++ ) cin >> a[i];
build(1,1,n);
string op;
int x,y;
while(m -- ){
cin >> op;
scanf("%d%d",&x,&y);
if(op == "Ask"){
maxv = 0,cnt = 0;
query(1,x,y);
cout<<maxv<<" "<<cnt<<endl;
}else{
modify(1,x,y);
}
}
return 0;
}