码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj4137 [FJOI2015]火星商店问题

时间:2015-10-13 00:14:18      阅读:840      评论:0      收藏:0      [点我收藏+]

标签:

  比较容易想到的做法是线段树套字典树,修改操作时在字典树上经过的节点维护一个最近被访问过的时间,这样询问操作只经过满足时间条件的节点,时间复杂度O(NlogN^2)但是因为线段树每个节点都要套个字典树,这样的话空间是不够的,不过由于可以离线处理,我们可以先把每个修改和询问操作所访问的线段树节点保存下来,然后一个个节点去做,这样的话空间复杂度就可以保证了。

 

代码

  1 #include<cstdio>
  2 #include<set>
  3 #include<vector>
  4 #define N 1000010
  5 #define M 10000010
  6 using namespace std;
  7 int l[N],r[N],n,m,i,a,typ,b,L,R,ti,ans[N],tot,p[N],cnt,flag;
  8 int s[M][2],t[M];
  9 vector<pair<int,int> > vec[N];
 10 vector<int> id[N];
 11 void build(int x,int a,int b)
 12 {
 13     int m;
 14     l[x]=a;r[x]=b;
 15     if (b-a>1)
 16     {
 17         m=(a+b)>>1;
 18         build(2*x,a,m);
 19         build(2*x+1,m,b);
 20     }
 21 }
 22 void insert(int x,int a,int b,pair<int,int> c,int typ)
 23 {
 24     int m;
 25     if (typ==0)
 26     {
 27         vec[x].push_back(c);
 28         id[x].push_back(typ);
 29     }
 30     if ((a<=l[x])&&(r[x]<=b))
 31     {
 32         if (typ)
 33         {
 34             vec[x].push_back(c);
 35             id[x].push_back(typ);
 36         }
 37         return; 
 38     }
 39     m=(l[x]+r[x])>>1;
 40     if (a<m) insert(2*x,a,b,c,typ);
 41     if (m<b) insert(2*x+1,a,b,c,typ);
 42 } 
 43 void cl(int x)
 44 {
 45     int i;
 46     for (i=1;i<=17;i++)
 47     {
 48         p[17-i+1]=x%2;
 49         x=x/2;
 50     }
 51 }
 52 void change(int x,int y)
 53 {
 54     int now,i;
 55     cl(x);
 56     now=1;
 57     for (i=1;i<=17;i++)
 58     {
 59         if (s[now][p[i]]==0) 
 60             s[now][p[i]]=++tot;
 61         now=s[now][p[i]];
 62         t[now]=max(t[now],y);
 63     }
 64 }
 65 int query(int x,int y)
 66 {
 67     int now,i,ans=0;
 68     cl(x);
 69     now=1;
 70     for (i=1;i<=17;i++)
 71     if ((s[now][1-p[i]])&&(t[s[now][1-p[i]]]>=y))
 72     {
 73         now=s[now][1-p[i]];
 74         ans=ans+(1<<(17-i));
 75     }
 76     else
 77     now=s[now][p[i]];
 78     return ans;
 79 }
 80 void gao(int x)
 81 {
 82     int i,a,b;
 83     for (i=1;i<=tot;i++)
 84     s[i][0]=s[i][1]=t[i]=0;
 85     tot=1;
 86     for (i=0;i<vec[x].size();i++)
 87     {
 88         a=vec[x][i].first;
 89         b=vec[x][i].second;
 90         if (id[x][i]==0)
 91         change(a,b);
 92         else
 93         ans[id[x][i]]=max(ans[id[x][i]],query(a,b));
 94     }
 95     if (r[x]-l[x]==1)
 96     return;
 97     gao(2*x);
 98     gao(2*x+1);
 99 } 
100 int main()
101 {
102     scanf("%d%d",&n,&m);
103     build(1,0,n);
104     for (i=1;i<=n;i++)
105     {
106         scanf("%d",&a); 
107         insert(1,i-1,i,make_pair(a,m+1),0);
108     }
109     ti=1;
110     for (i=1;i<=m;i++)
111     {
112         scanf("%d",&typ);
113         if (typ==1)
114         {
115             scanf("%d%d%d%d",&L,&R,&a,&b);
116             insert(1,L-1,R,make_pair(a,ti-b+1),++cnt);
117         }
118         else
119         {
120             ti++;
121             scanf("%d%d",&a,&b);
122             insert(1,a-1,a,make_pair(b,ti),0);
123         }
124     }
125     gao(1);
126     for (i=1;i<=cnt;i++)
127     printf("%d\n",ans[i]);
128 }

 

bzoj4137 [FJOI2015]火星商店问题

标签:

原文地址:http://www.cnblogs.com/fzmh/p/4873043.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!