模拟赛的一道莫队题

Posted yyc-jack-0920

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模拟赛的一道莫队题相关的知识,希望对你有一定的参考价值。

题目大意:

每一天都会给一段区间加上一个权值

一些查询 查询 [l,r] 天数内操作的权值最大的点与它的位置

思路:

莫队+线段树

先把操作都连线下来

然后直接莫队套上线段树

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<queue>
 8 #include<map>
 9 #define inf 2139062143
10 #define ll long long
11 #define MAXN 50100
12 using namespace std;
13 inline int read()
14 {
15     int x=0,f=1;char ch=getchar();
16     while(!isdigit(ch)) {if(ch==-) f=-1;ch=getchar();}
17     while(isdigit(ch)) {x=x*10+ch-0;ch=getchar();}
18     return x*f;
19 }
20 int n,m,block[MAXN],ans[MAXN],Ans[MAXN];
21 namespace Seg_tree
22 {
23     struct node{int mx,res,tag;}tr[MAXN<<2];
24     void build(int k,int l,int r)
25     {
26         tr[k].mx=tr[k].tag=0,tr[k].res=l;
27         if(l==r) return ;
28         int mid=(l+r)>>1;
29         build(k<<1,l,mid);build(k<<1|1,mid+1,r);
30     }
31     void upd(int k)
32     {
33         if(tr[k<<1].mx>=tr[k<<1|1].mx) tr[k].mx=tr[k<<1].mx,tr[k].res=tr[k<<1].res;
34         else tr[k].mx=tr[k<<1|1].mx,tr[k].res=tr[k<<1|1].res;
35     }
36     void pshd(int k)
37     {
38         tr[k<<1].tag+=tr[k].tag,tr[k<<1|1].tag+=tr[k].tag;
39         tr[k<<1].mx+=tr[k].tag,tr[k<<1|1].mx+=tr[k].tag;
40         tr[k].tag=0;
41     }
42     void mdf(int k,int l,int r,int a,int b,int x)
43     {
44         if(l==a&&r==b) {tr[k].mx+=x,tr[k].tag+=x;return ;}
45         int mid=(l+r)>>1;
46         if(tr[k].tag) pshd(k);
47         if(b<=mid) mdf(k<<1,l,mid,a,b,x);
48         else if(a>mid) mdf(k<<1|1,mid+1,r,a,b,x);
49         else {mdf(k<<1,l,mid,a,mid,x);mdf(k<<1|1,mid+1,r,mid+1,b,x);}
50         upd(k);
51     }
52 }
53 using namespace Seg_tree;
54 struct ask{int l,r,id;}q[MAXN];
55 struct opt{int l,r;}t[MAXN];
56 bool cmp(ask a,ask b)
57 {
58     if(block[a.l]==block[b.l])
59         return a.r<b.r||a.r==b.r;
60     else return a.l<b.l;
61 }
62 int main()
63 {
64     freopen("magic.in","r",stdin);
65     freopen("magic.out","w",stdout);
66     for(int x=read(),i=1;i<=x;i++) t[i].l=read(),t[i].r=read(),n=max(n,t[i].r);
67     m=read();    
68     int sz=sqrt(m);
69     for(int i=1;i<=m;i++) q[i].l=read(),q[i].r=read(),q[i].id=i,block[i]=(i-1)/sz+1;
70     sort(q+1,q+m+1,cmp);
71     int l=1,r=0,pos= 0;
72     build(1,1,n);
73     for(int i=1;i<=m;i++)
74     {
75         while(l>q[i].l) {l--;mdf(1,1,n,t[l].l,t[l].r,1);}
76         while(r<q[i].r) {r++;mdf(1,1,n,t[r].l,t[r].r,1);}
77         while(l<q[i].l) {mdf(1,1,n,t[l].l,t[l].r,-1);l++;}
78         while(r>q[i].r) {mdf(1,1,n,t[r].l,t[r].r,-1);r--;}
79         ans[q[i].id]=tr[1].mx,Ans[q[i].id]=tr[1].res;
80     }
81     for(int i=1;i<=m;i++) printf("%d %d\n",Ans[i],ans[i]);
82 }
View Code

 

以上是关于模拟赛的一道莫队题的主要内容,如果未能解决你的问题,请参考以下文章

P1494 [国家集训队]小Z的袜子

loj#6285 数列分块入门 9 ( 回 滚 )

Luogu P4462 [CQOI2018]异或序列

洛谷P3245 [HNOI2016]大数 莫队

P1494 小Z的袜子 普通莫队

bzoj4241/AT1219 历史研究(回滚莫队)