zoukankan      html  css  js  c++  java
  • BZOJ 2244 [SDOI2011]拦截导弹 (三维偏序CDQ+线段树)

    题目大意:

    洛谷传送门

    不愧为SDOI的duliu题

    第一问?二元组的最长不上升子序列长度?裸的三维偏序问题,直接上$CDQ$

    由于是不上升,需要查询某一范围的最大值,并不是前缀最大值,建议用线段树实现

    第二问是个什么玩意??

    画画图发现需要正反各做一次$CDQ$来统计

    如果某个位置正反的答案$-1$就是最长长度

    那么它被选择的次数就是 正着统计作为末尾的次数*反着统计作为末尾的次数

    概率就是这个值/总次数

    又发现某个位置作为末尾的次数可能非常非常大!

    比如$1;1;2;2;3;3;4;4;5;5....$这个值甚至达到了$2^{n/2}$

    而题目又是让我们求概率,所以这个次数必须要用$double$存

    蒟蒻的代码写得比较恶心..

    另外听一些神犇说$sort$中的$cmp$里不能写$<=$或$>=$,不然会$RE$

      1 #include <vector>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #define N1 50100
      6 #define ll long long
      7 #define dd double
      8 #define inf 0x3f3f3f3f3f3f3f3fll
      9 using namespace std;
     10 
     11 int gint()
     12 {
     13     int ret=0,fh=1;char c=getchar();
     14     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
     15     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
     16     return ret*fh;
     17 }
     18 int n,m,mh,mv,K;
     19 inline void chk(int &ma,dd &sum,int w,dd num)
     20 {
     21     if(w>ma) ma=w,sum=num;
     22     else if(w==ma) sum+=num;
     23 }
     24 
     25 struct SEG{
     26 int ma[N1<<2]; dd sum[N1<<2];
     27 void pushup(int rt)
     28 {
     29     ma[rt]=0; sum[rt]=0;
     30     chk(ma[rt],sum[rt],ma[rt<<1],sum[rt<<1]);
     31     chk(ma[rt],sum[rt],ma[rt<<1|1],sum[rt<<1|1]);
     32 }
     33 void update(int x,int l,int r,int rt,int w,dd num)
     34 {
     35     if(l==r) { chk(ma[rt],sum[rt],w,num); return; }
     36     int mid=(l+r)>>1; 
     37     if(x<=mid) update(x,l,mid,rt<<1,w,num);
     38     else update(x,mid+1,r,rt<<1|1,w,num);
     39     pushup(rt);
     40 }
     41 void query(int L,int R,int l,int r,int rt,int &w,dd &num)
     42 {
     43     if(L<=l&&r<=R) { chk(w,num,ma[rt],sum[rt]); return; }
     44     int mid=(l+r)>>1;
     45     if(L<=mid) query(L,R,l,mid,rt<<1,w,num);
     46     if(R>mid) query(L,R,mid+1,r,rt<<1|1,w,num);
     47 }
     48 void clr(int x,int l,int r,int rt)
     49 {
     50     ma[rt]=0; sum[rt]=0;
     51     if(l==r) return; int mid=(l+r)>>1;
     52     if(x<=mid) clr(x,l,mid,rt<<1);
     53     else clr(x,mid+1,r,rt<<1|1);
     54 }
     55 }s;
     56 struct node{int h,v,t,ans; dd sum;}a[N1],c[N1],tmp[N1];
     57 int h[N1],v[N1],que[N1],tl;
     58 
     59 int cmp1(node s1,node s2){ if(s1.h!=s2.h) return s1.h>s2.h; return s1.v>=s2.v; }
     60 int cmp2(node s1,node s2){ if(s1.h!=s2.h) return s1.h<s2.h; return s1.v<=s2.v; }
     61 int cmpp(node s1,node s2){ if(s1.h!=s2.h) return s1.h>s2.h; return s1.v>s2.v; }
     62 int cmpn(node s1,node s2){ if(s1.h!=s2.h) return s1.h<s2.h; return s1.v<s2.v; }
     63 
     64 void CDQ1(int L,int R)
     65 {
     66     if(R-L<=1) return;
     67     int M=(L+R)>>1,i,j,k,cnt;
     68     for(i=L,j=M,k=L;k<R;k++)
     69     {
     70         if(a[k].t<M) tmp[i++]=a[k];
     71         else tmp[j++]=a[k];
     72     }
     73     for(k=L;k<R;k++) a[k]=tmp[k];
     74     CDQ1(L,M);
     75     for(i=L,j=M;i<M&&j<R;)
     76     {
     77         if(cmp1(a[i],a[j])) { s.update(a[i].v,1,mv,1,a[i].ans+1,a[i].sum); que[++tl]=i; i++; }
     78         else { s.query(a[j].v,mv,1,mv,1,a[j].ans,a[j].sum); j++; }
     79     }
     80     while(j<R) { s.query(a[j].v,mv,1,mv,1,a[j].ans,a[j].sum); j++;}
     81     while(tl) { s.clr(a[que[tl--]].v,1,mv,1); }
     82     CDQ1(M,R);
     83     for(i=L,j=M,cnt=0;i<M&&j<R;)
     84     {
     85         if(cmp1(a[i],a[j])) { tmp[++cnt]=a[i]; i++; }
     86         else { tmp[++cnt]=a[j]; j++;}
     87     }
     88     while(i<M) tmp[++cnt]=a[i++];
     89     while(j<R) tmp[++cnt]=a[j++];
     90     for(k=L;k<R;k++) a[k]=tmp[k-L+1];
     91 }
     92 void CDQ2(int L,int R)
     93 {
     94     if(R-L<=1) return;
     95     int M=(L+R)>>1,i,j,k,cnt;
     96     for(i=L,j=M,k=L;k<R;k++)
     97     {
     98         if(a[k].t<M) tmp[i++]=a[k];
     99         else tmp[j++]=a[k];
    100     }
    101     for(k=L;k<R;k++) a[k]=tmp[k];
    102     CDQ2(L,M);
    103     for(i=L,j=M;i<M&&j<R;)
    104     {
    105         if(cmp2(a[i],a[j])) { s.update(a[i].v,1,mv,1,a[i].ans+1,a[i].sum); que[++tl]=i; i++; }
    106         else { s.query(1,a[j].v,1,mv,1,a[j].ans,a[j].sum); j++; }
    107     }
    108     while(j<R) { s.query(1,a[j].v,1,mv,1,a[j].ans,a[j].sum); j++;}
    109     while(tl) { s.clr(a[que[tl--]].v,1,mv,1); }
    110     CDQ2(M,R);
    111     for(i=L,j=M,cnt=0;i<M&&j<R;)
    112     {
    113         if(cmp2(a[i],a[j])) { tmp[++cnt]=a[i]; i++; }
    114         else { tmp[++cnt]=a[j]; j++;}
    115     }
    116     while(i<M) tmp[++cnt]=a[i++];
    117     while(j<R) tmp[++cnt]=a[j++];
    118     for(k=L;k<R;k++) a[k]=tmp[k-L+1];
    119 }
    120 dd ret[N1];
    121 int p[N1];
    122 int de;
    123 
    124 int main()
    125 {
    126     scanf("%d",&n);
    127     int i,j,x,y,ans=0; dd sum=0;
    128     for(i=1;i<=n;i++) { h[i]=a[i].h=gint(); v[i]=a[i].v=gint(); a[i].t=i; a[i].ans=1; a[i].sum=1; }
    129     sort(h+1,h+n+1); mh=unique(h+1,h+n+1)-(h+1); sort(v+1,v+n+1); mv=unique(v+1,v+n+1)-(v+1); 
    130     for(i=1;i<=n;i++) { a[i].h=lower_bound(h+1,h+mh+1,a[i].h)-h; a[i].v=lower_bound(v+1,v+mv+1,a[i].v)-v;}
    131     sort(a+1,a+n+1,cmpp);
    132     CDQ1(1,n+1); 
    133     for(i=1;i<=n;i++) { c[i]=a[i]; p[a[i].t]=i; chk(ans,sum,a[i].ans,a[i].sum); }
    134     sort(a+1,a+n+1,cmpn); for(i=1;i<=n;i++) { a[i].ans=1; a[i].sum=1; a[i].t=n-a[i].t+1; }
    135     CDQ2(1,n+1);
    136     for(i=1;i<=n;i++) 
    137     {
    138         j=p[n-a[i].t+1];
    139         if(a[i].ans+c[j].ans-1<ans) ret[c[j].t]=0;
    140         else ret[c[j].t]=1.0*c[j].sum*a[i].sum/sum;
    141     }
    142     printf("%d
    ",ans);
    143     for(i=1;i<=n;i++) printf("%.5lf ",ret[i]);
    144     puts(""); return 0;
    145 }
  • 相关阅读:
    进程间通信
    图形的保存与重绘
    mysql记录1
    文件操作
    多线程及聊天室程序
    健康是成功之本
    文档与串行化
    HTML网页制作基础
    Hook和数据库访问
    C++基础笔记1
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10208615.html
Copyright © 2011-2022 走看看