FJ省队集训DAY3 T1

思路:我们考虑如果取掉一个部分,那么能影响到最优解的只有离它最近的那两个部分。

因此我们考虑堆维护最小的部分,离散化离散掉区间,然后用线段树维护区间有没有雪,最后用平衡树在线段的左右端点上面维护最小的id

我讲的貌似不是很清楚。。

还有,蜜汁80分,打死也改不出来。。

  1 #include<cstdio>
  2 #include<cmath>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<algorithm>
  6 struct node{
  7     int l,r,cnt,id;
  8 }a[1200005];
  9 struct segment{
 10     int l,r,v; 
 11     segment(){}
 12     segment(int l0,int r0,int v0):l(l0),r(r0),v(v0){}
 13 }t[5000005];
 14 struct treap{
 15     int l,r,rnd,v;
 16 }tt[5000005];
 17 int tag[5000005],vis[1000005],Tcase;
 18 int len[1000005],next[1500005],before[1500005],pos[1000005],heap[1000005];
 19 int o[1500005],p[1000005],sz,Id[1000005],pls[1500005];
 20 int c[2500005],Cnt,sb,rt1[1500005],rt2[1500005],all[500006];
 21 int tot,n,Len;
 22 int read(){
 23     int t=0,f=1;char ch=getchar();
 24     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
 25     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
 26     return t*f;
 27 }
 28 bool cmp(node a,node b){
 29     return a.r-a.l<b.r-b.l;
 30 }
 31 void push_up(int x){
 32     while (x>1){
 33         if (len[x/2]>len[x]||(len[x/2]==len[x]&&heap[x/2]>heap[x])) std::swap(len[x/2],len[x]),std::swap(heap[x/2],heap[x]),std::swap(pos[heap[x]],pos[heap[x/2]]);
 34         else break;
 35         x/=2;
 36     }
 37 }
 38 void push_down(int x){
 39     int j;
 40     while (x*2<=tot){
 41         if (x*2==tot) j=2*x;
 42         else if (len[2*x]<len[2*x+1]||(len[2*x]==len[2*x+1]&&heap[2*x]<heap[2*x+1])) j=2*x;
 43         else j=2*x+1;
 44         if (len[x]>len[j]||(len[x]==len[j]&&heap[j]<heap[x])){
 45             std::swap(len[x],len[j]);
 46             std::swap(heap[x],heap[j]);
 47             std::swap(pos[heap[x]],pos[heap[j]]);
 48         }
 49         x=j;
 50     }
 51 }
 52 void add_heap(int x,int v){
 53     heap[++tot]=x;
 54     len[tot]=v;
 55     pos[x]=tot;
 56     push_up(tot);
 57 }
 58 void delete_heap(int x){
 59     int Pos=pos[x];
 60     heap[Pos]=heap[tot];
 61     len[Pos]=len[tot];
 62     pos[heap[tot]]=Pos;
 63     tot--;
 64     push_down(Pos);
 65 }
 66 void modify_heap(int x,int y){
 67     int Pos=pos[x];
 68     len[Pos]=y;
 69     push_up(Pos);
 70 }
 71 void build(int k,int l,int r){
 72     if (l==r){
 73         t[k].v=o[l];
 74         t[k].l=t[k].r=l;
 75         return;
 76     }
 77     int mid=(l+r)>>1;
 78     build(k*2,l,mid);
 79     build(k*2+1,mid+1,r);
 80     t[k].v=t[k*2].v+t[k*2+1].v;
 81     t[k].l=std::min(t[k*2].l,t[k*2+1].l);
 82     t[k].r=std::max(t[k*2].r,t[k*2+1].r);
 83 }
 84 void pushdown(int k,int l,int r){
 85     if (!tag[k]||l==r) return;
 86     tag[k]=0;
 87     t[k*2].v=t[k*2+1].v=0;
 88     tag[k*2]=tag[k*2+1]=1;
 89     t[k*2].l=t[k*2+1].l=Len+1;
 90     t[k*2].r=t[k*2+1].r=0;
 91 }
 92 void modify(int k,int l,int r,int x,int y){
 93     if (l>r) return;
 94     if (l>y||r<x) return;
 95     pushdown(k,l,r);
 96     if (l==x&&r==y){
 97         tag[k]=1;
 98         t[k].l=Len+1;
 99         t[k].r=0;
100         t[k].v=0;
101         pushdown(k,l,r);
102         return;
103     }
104     int mid=(l+r)>>1;
105     if (y<=mid) modify(k*2,l,mid,x,y);
106     else
107     if (x>mid) modify(k*2+1,mid+1,r,x,y);
108     else modify(k*2,l,mid,x,mid),modify(k*2+1,mid+1,r,mid+1,y);
109     t[k].v=t[k*2].v+t[k*2+1].v;
110     t[k].l=std::min(t[k*2].l,t[k*2+1].l);
111     t[k].r=std::max(t[k*2].r,t[k*2+1].r);
112 }
113 segment query(int k,int l,int r,int x,int y){
114     if (x>y) return segment(x,y,0);
115     pushdown(k,l,r);
116     if (l==x&&r==y){
117         return segment(t[k].l,t[k].r,t[k].v);
118     }
119     int mid=(l+r)>>1;
120     if (y<=mid) return query(k*2,l,mid,x,y);
121     else
122     if (x>mid) return query(k*2+1,mid+1,r,x,y);
123     else{
124     segment t1=query(k*2,l,mid,x,mid);
125     segment t2=query(k*2+1,mid+1,r,mid+1,y);
126     return segment(std::min(t1.l,t2.l),std::max(t1.r,t2.r),t1.v+t2.v);
127     }
128 }
129 int find(int x){
130     int l=1,r=p[0];
131     while (l<=r){
132         int mid=(l+r)>>1;
133         if (p[mid]==x) return Id[mid];
134         if (p[mid]<x) l=mid+1;
135         else r=mid-1;
136     }
137 }
138 void sbpianfen1(){
139     int T=n;
140     for (int i=1;i<=n;i++) 
141      a[i].l=read(),a[i].r=read(),a[i].id=i,a[i].cnt=a[i].r-a[i].l+1,add_heap(i,a[i].r-a[i].l+1),p[++p[0]]=a[i].l,p[++p[0]]=a[i].r;
142     std::sort(p+1,p+1+p[0]);int j=1;
143     for (int i=2;i<=p[0];i++)
144      if (p[i]!=p[j]) p[++j]=p[i];p[0]=j;
145     
146     for (int i=1;i<=p[0];i++) 
147      if (p[i]!=p[i-1]){
148         o[++sz]=p[i]-p[i-1]-1;
149         o[++sz]=1;
150         Id[i]=sz;
151      }
152     Len=sz; 
153     for (int i=1;i<=n;i++)
154      a[i].l=find(a[i].l),a[i].r=find(a[i].r); 
155     build(1,1,Len);
156     a[n+1].cnt=0x7fffffff;
157     while (T--){
158         int mn=n+1;
159         for (int i=n;i>=1;i--)
160          if (a[i].cnt<=a[mn].cnt&&!vis[i]) mn=i;
161         printf("%d\n",mn);vis[mn]=1;
162         modify(1,1,Len,a[mn].l,a[mn].r);
163         for (int i=1;i<=n;i++){
164           segment t1=query(1,1,Len,a[i].l,a[i].r);    
165           a[i].cnt=t1.v;
166         }
167     }
168 }
169 void lturn(int &k){
170     if (!k) return;
171     int TT=tt[k].r;tt[k].r=tt[TT].l;tt[TT].l=k;k=TT;
172 }
173 void rturn(int &k){
174     if (!k) return;
175     int TT=tt[k].l;tt[k].l=tt[TT].r;tt[TT].r=k;k=TT;
176 }
177 void insert(int &k,int v){
178     if (!k){
179         if (Cnt) k=c[Cnt--];else k=++sb;
180         tt[k].l=tt[k].r=0;tt[k].rnd=rand();
181         tt[k].v=v;
182         all[v]++;
183         return;
184     }
185     if (tt[k].v==v) {all[v]++;return;}
186     if (tt[k].v<v){
187         insert(tt[k].r,v);
188         if (tt[tt[k].r].rnd<tt[k].rnd) lturn(k);
189     }else{
190         insert(tt[k].l,v);
191         if (tt[tt[k].l].rnd<tt[k].rnd) rturn(k);
192     }
193 }
194 void del(int &k,int v){
195     if (!k) return;
196     if (tt[k].v==v){
197         if (tt[k].l*tt[k].r==0){
198             c[++Cnt]=k;
199             k=tt[k].l+tt[k].r;
200             all[v]--;
201             return;
202         }
203         if (tt[tt[k].l].rnd<tt[tt[k].r].rnd){
204             rturn(k);
205             del(k,v);
206         }else{
207             lturn(k);
208             del(k,v);
209         }
210         return;
211     }
212     if (tt[k].v<v) del(tt[k].r,v);
213     else del(tt[k].l,v);
214 }
215 int find_treap(int k){
216     while (tt[k].l!=0) k=tt[k].l;
217     return tt[k].v;
218 }
219 bool findit(int k,int x){
220     if (!k) return 0;
221     if (tt[k].v==x) return 1;
222     else if (tt[k].v<x) return findit(tt[k].r,x);
223     else return findit(tt[k].l,x);
224 }
225 void Gwork(){
226     Tcase=Tcase;
227 }
228 void updata(int x,int id){
229     if (id==1) x=pls[find_treap(rt1[a[x].l])];
230     else if (id==2) x=pls[find_treap(rt2[a[x].r])];
231     if (a[x].l>a[x].r) return;
232     segment t1=query(1,1,Len,a[x].l,a[x].r);
233     a[x].cnt=t1.v;
234     if (a[x].id==51612&&(a[x].l==206449||a[x].r==206449)) Gwork();
235     del(rt1[a[x].l],a[x].id);
236     del(rt2[a[x].r],a[x].id);
237     a[x].l=t1.l;
238     a[x].r=t1.r;
239     insert(rt1[a[x].l],a[x].id);
240     insert(rt2[a[x].r],a[x].id);
241     modify_heap(a[x].id,a[x].cnt);
242 }
243 void sbpianfen3(){
244     for (int i=1;i<=n;i++) 
245      a[i].l=read(),a[i].r=read(),a[i].cnt=a[i].r-a[i].l+1,a[i].id=i,add_heap(i,a[i].r-a[i].l+1),p[++p[0]]=a[i].l,p[++p[0]]=a[i].r;
246     std::sort(p+1,p+1+p[0]);int j=1;
247     for (int i=2;i<=p[0];i++)
248      if (p[i]!=p[j]) p[++j]=p[i];p[0]=j;
249     for (int i=1;i<=p[0];i++) 
250      if (p[i]!=p[i-1]){
251         o[++sz]=p[i]-p[i-1]-1;
252         o[++sz]=1;
253         Id[i]=sz;
254      }
255     Len=sz; 
256     for (int i=1;i<=n;i++)
257      a[i].l=find(a[i].l),a[i].r=find(a[i].r),insert(rt1[a[i].l],i),insert(rt2[a[i].r],i); 
258     for (int i=1;i<=n;i++) 
259      pls[a[i].id]=i;
260     for (int i=2;i<=n;i++) before[i]=i-1;
261     for (int i=1;i<n;i++) next[i]=i+1;
262     int T=n;
263     build(1,1,Len);
264     while (T--){
265         Tcase++;
266         int x=heap[1];printf("%d\n",x);
267         delete_heap(x);
268         if (a[x].l>a[x].r){
269             int t1=before[pls[x]],t2=next[pls[x]];
270             next[t1]=t2;
271             before[t2]=t1;
272             continue;
273         }
274         if (Tcase==2872) Gwork();
275         modify(1,1,Len,a[pls[x]].l,a[pls[x]].r);
276         if (before[pls[x]]) updata(before[pls[x]],1);
277         if (next[pls[x]]) updata(next[pls[x]],2);
278         int t1=before[pls[x]],t2=next[pls[x]];
279         next[t1]=t2;
280         before[t2]=t1;
281     }
282 }
283 int main(){
284     Len=read();n=read();
285     if (n<=1000) {sbpianfen1();fclose(stdin);fclose(stdout);return 0;}
286     sbpianfen3();
287     fclose(stdin);fclose(stdout);
288     return 0;
289 }

 

转载于:https://www.cnblogs.com/qzqzgfy/p/5645004.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值