Topic: Given a sequence, each element is a two-tuple, equal probability of choosing an LIS, the length of the LIS and the probability of each element being selected
The first question CDQ divided the naked
The second question is the answer with the number of LIS/total LIS number where each element resides
Each element is located in the LIS itself must be selected, and then count the previous scheme number and the following scheme number
Take the previous scheme number as an example, so that f[x] is the length of the LIS ending with x, then there is the DP equation:
G[I]=ΣG[J] (F[J]+1=F[I],J<I,A[J].X<A[I].X,A[J].Y<A[I].Y)
Sort all elements by the F value, layered DP, each layer DP is a three-dimensional partial order, on the CDQ division and then it's better to engage
(I lazy wrote a two-dimensional tree-like array qaq)
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 50500using namespace Std;typedef double ld;int n,ans,tot;int f[m];ld g[m],h[m],total;struct abcd{int x, y;} *a[m],*_a[m],mempool[m];bool Compare (ABCD *a1,abcd *a2) {if (a1->x! = a2->x) return a1->x < a2->x; return A1 ->y < A2->y;} BOOL _compare (int x,int y) {if (f[x]! = F[y]) return f[x] < f[y]; return x < y;} void discretization () {static pair<int,int*> b[m];int i;for (i=1;i<=n;i++) B[i]=make_pair (-a[i]->x,&a [i]->x); sort (b+1,b+n+1); for (tot=0,i=1;i<=n;i++) {if (i==1| | B[i].first!=b[i-1].first) ++tot;*b[i].second=tot;} for (i=1;i<=n;i++) B[i]=make_pair (-a[i]->y,&a[i]->y), sort (b+1,b+n+1), for (tot=0,i=1;i<=n;i++) {if ( i==1| | B[i].first!=b[i-1].first) ++tot;*b[i].second=tot;}} namespace Bit{int c[m],tim[m],t;void Initialize () {++t;} void Update (int x,int y) {for (; x<=n;x+=x&-x) {if (tim[x]!=t) Tim[x]=t,c[x]=0;c[x]=max (c[x],y);}} int Get_aNS (int x) {int re=0;for (; x;x-=x&-x) if (tim[x]==t) Re=max (re,c[x]); return re;}} void Cdq_divide_and_conquer (int l,int r) {using namespace Bit;int i,j,mid=l+r>>1;if (l==r) {F[mid]++;ans=max (ans, F[mid]); return;} int L1=l,l2=mid+1;for (i=l;i<=r;i++) if (a[i]-mempool<=mid) _a[l1++]=a[i];else_a[l2++]=a[i];memcpy (A+l,_a+l, sizeof (A[0]) * (r-l+1)); Cdq_divide_and_conquer (L,mid); Initialize (); for (j=l,i=mid+1;i<=r;i++) {for (;j<=mid&&a[j]->x< =a[i]->x;j++) Update (A[j]->y,f[a[j]-mempool]); F[a[i]-mempool]=max (F[a[i]-mempool],get_ans (A[i]->y));} Cdq_divide_and_conquer (mid+1,r); L1=l;l2=mid+1;for (i=l;i<=r;i++) if (l2>r | | l1<=mid && Compare (a[l1 ],A[L2]) _a[i]=a[l1++];else_a[i]=a[l2++];memcpy (a+l,_a+l,sizeof (a[0]) * (r-l+1));} namespace Bidimensional_bit{namespace hash_table{struct List{int x,y;ld val; List *next; List () {}list (int _,int __,list *___): X (_), Y (__), Val (0), next (___) {}}mempool[12000000],*c=mempool,*head[1031][1301] ; int Tim[1031][1301],t;void Initialize () {c=mempool;++t;} ld& Hash (int x,int y) {int pos1=x%1031,pos2=y%1301; List *temp;if (tim[pos1][pos2]!=t) tim[pos1][pos2]=t,head[pos1][pos2]=0;for (temp=head[pos1][pos2];temp;temp=temp- >next) if (temp->x==x&&temp->y==y) return Temp->val;return (head[pos1][pos2]=new List (x,y,head[ POS1][POS2])->val;} LD get_hash (int x,int y) {int pos1=x%1031,pos2=y%1301; List *temp;if (tim[pos1][pos2]!=t) tim[pos1][pos2]=t,head[pos1][pos2]=0;for (temp=head[pos1][pos2];temp;temp=temp- >next) if (temp->x==x&&temp->y==y) return Temp->val;return 0;}} Using namespace hash_table;void Update (int x,int y,ld val,int flag) {int i,j;for (i=x;i&&i<=n;i+=flag* (i& -i)) for (j=y;j&&j<=n;j+=flag* (J&-J)) Hash (i,j) +=val;} LD Get_ans (int x,int y,int flag) {ld Re=0;int i,j;for (i=x;i&&i<=n;i+=flag* (I&-i)) for (j=y;j&&j <=n;j+=flag* (J&-J)) Re+=get_hash (I,J); return re;}} int main () {//freopen ("3756.in", "R", stdin),//freopen ("3756.out", "w", stdout); int i,j;cIn>>n;for (i=1;i<=n;i++) {scanf ("%d%d", &mempool[i].x,&mempool[i].y); a[i]=&mempool[i];} Discretization (); sort (a+1,a+n+1,compare); Cdq_divide_and_conquer (1,n); cout<<ans<<endl;static int a[m];for (i=1;i<=n;i++) A[i]=i;sort (a+1,a+n+ 1,_compare); for (i=1;i<=n&&f[a[i]]==1;i++) g[a[i]]=1;for (j=1;i<=n;i++) {if (F[a[i]]!=f[a[i-1]]) {for ( ; f[a[j]]+1!=f[a[i]];j++); Bidimensional_bit::initialize ();} for (; a[j]<a[i]&&f[a[j]]==f[a[i]]-1;j++) bidimensional_bit::update (mempool[a[j]].x,mempool[a[j]].y,g[ a[j]],1); G[a[i]]=bidimensional_bit::get_ans (mempool[a[i]].x,mempool[a[i]].y,-1);} for (i=n;i&&f[a[i]]==ans;i--) h[a[i]]=1;for (j=n;i;i--) {if (f[a[i]]!=f[a[i+1])} {for (; f[a[j]]-1!=f[a[i]); j--); Bidimensional_bit::initialize ();} for (; a[j]>a[i]&&f[a[j]]==f[a[i]]+1;j--) bidimensional_bit::update (mempool[a[j]].x,mempool[a[j]].y,h[ A[J]],-1); H[a[i]]=bidimensional_bit::get_ans (mempool[a[i]].x,mempool[a[i]].y,1);} for (i=1;i<=n&&f[a[i]]==1;i++) total+=h[a[i]];for (i=1;i<=n;i++) printf ("%.10lf%c", (double) (g[i]*h[i]/total), i==n? ' \ n ': '); return 0;}
Bzoj 2244 SDOI2011 Intercept missile CDQ Division/two-D tree-like array