• 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
    ",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
    ",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 }
  • 相关阅读:
    实现连续测试,要做的事情【译】
    Go语言HTTPServer开发的六种实现
    JSON必知必会【PDF+视频教程】
    给JSONObject添加自定义遍历方法
    利用守护线程隐式关闭线程池
    从错误中学习
    Groovy动态添加方法和属性及Spock单测
    持续测试、持续集成、持续交付、持续部署和DevOps
    有关OAuth 2.0简化模式中步骤D-F的解释
    Spring笔记(五):bean的自动装配
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5645004.html
Copyright © 2020-2023  润新知