• 4.1 模拟赛


    T1 luogu 5249

    题目大意:

    有$n$个人按顺序坐成一圈玩游戏,从$1$号开始每次抛硬币,如果是正面就出局,无论结果如何都把硬币给下一个没出局的人

    这个硬币概率是正面的概率为$p$由一个分数$frac{a}{b}$的形式给出$a,b$,问$1-n$号人留到最后的概率在$mod 998244353$下的数

    思路:

    设$f_{i,j}$表示总共还剩$i$个人的时候,若当前抛硬币的人编号为$1$,编号为$j$的人作为最后一个人的概率

    则容易推出方程$f_{i,j}=p*f_{i-1,j-1}+q*f_{i,j-1}$,由于是环形所以需要消元

    因为对每个$i$,需要所有$i-1$都已知才可以,这样我们一行一行使用高斯消元复杂度为$n^4$

    考虑手动推系数,把一行内所有的$f_{i,j}$全部用$f_{i,1}$代替

    推出$f_{i,1}$的系数和其余常数项,因为每一行的和都是$1$,算出$f_{i,1}$之后再带回去即可,复杂度$n^2$

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #include<map>
    10 #include<set>
    11 #define ll long long
    12 #define db double
    13 #define inf 2139062143
    14 #define MOD 998244353
    15 #define MAXN 5010
    16 #define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i)
    17 #define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i)
    18 #define ren for(register int i=fst[x];i;i=nxt[i])
    19 #define mem(x,i) memset(x,i,sizeof(x))
    20 #define pb(i,x) vec[i].push_back(x)
    21 #define pls(a,b) (a+b)%MOD
    22 #define mns(a,b) (a-b+MOD)%MOD
    23 #define mul(a,b) (1LL*(a)*(b))%MOD
    24 using namespace std;
    25 inline int read()
    26 {
    27     int x=0,f=1;char ch=getchar();
    28     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    29     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    30     return x*f;
    31 }
    32 int n,f[MAXN][MAXN],p,q,sum,k,tmp,s;
    33 int q_pow(int bas,int t,int res=1)
    34 {
    35     for(;t;t>>=1,bas=mul(bas,bas))
    36         if(t&1) res=mul(res,bas);return res;
    37 }
    38 #define inv(x) q_pow(x,MOD-2)
    39 int main()
    40 {
    41     freopen("A.in","r",stdin);freopen("A.out","w",stdout);
    42     int a=read(),b=read();n=read();p=mul(inv(b),a),q=mns(1,p);
    43     f[1][1]=1;rep(i,2,n)
    44     {
    45         s=sum=0,k=tmp=1;rep(j,2,i) tmp=mul(tmp,q),k=pls(k,tmp),
    46             s=pls(mul(s,q),mul(p,f[i-1][j-1])),sum=pls(sum,s);
    47         f[i][1]=mul(mns(1,sum),inv(k));rep(j,2,i)
    48             f[i][j]=pls(mul(p,f[i-1][j-1]),mul(q,f[i][j-1]));
    49     }
    50     rep(i,1,n) printf("%d ",f[n][i]);
    51 }
    View Code

    T2 

    题目大意:

    有一个长度为$n$的字符串,字符集为$n$

    $Q$组询问,形如$l,r$,询问删除一个左端点$leq l$,右端点$geq r$的子串后,剩下的部分可以形成的不同串的数量

    思路:

    有一个可以感性理解的结论为 $ans=$所有子串数量减去两边每种字符的数量乘积之和

    然后使用莫队,维护左右两边的数量即可

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #include<map>
    10 #include<set>
    11 #define ll long long
    12 #define db double
    13 #define inf 2139062143
    14 #define MAXN 100100
    15 #define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i)
    16 #define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i)
    17 #define ren for(register int i=fst[x];i;i=nxt[i])
    18 #define pb(i,x) tot[i].push_back(x)
    19 #define pls(a,b) (a+b)%MOD
    20 #define mns(a,b) (a-b+MOD)%MOD
    21 #define mul(a,b) (1LL*(a)*(b))%MOD
    22 using namespace std;
    23 inline int read()
    24 {
    25     int x=0,f=1;char ch=getchar();
    26     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    27     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    28     return x*f;
    29 }
    30 int n,m,g[MAXN],bl[MAXN],lnum[MAXN],rnum[MAXN],sz;
    31 ll ans[MAXN],res;struct ask{int l,r,t,id;}q[MAXN];
    32 bool cmp(ask a,ask b){return bl[a.l]<bl[b.l]||(bl[a.l]==bl[b.l]&&a.r<b.r);}
    33 int main()
    34 {
    35     freopen("B.in","r",stdin);freopen("B.out","w",stdout);
    36     n=read(),sz=sqrt(n);rep(i,1,n) g[i]=read(),bl[i]=(i-1)/sz;g[n+1]=n+1;
    37     m=read();rep(i,1,m) q[i].l=read()-1,q[i].r=read()+1,q[i].id=i;
    38     sort(q+1,q+m+1,cmp);int l=0,r=n+1;rep(i,1,m)
    39     {
    40         while(l<q[i].l) {l++;res+=rnum[g[l]],lnum[g[l]]++;}
    41         while(l>q[i].l) {res-=rnum[g[l]],lnum[g[l]]--;l--;}
    42         while(r>q[i].r) {r--;res+=lnum[g[r]],rnum[g[r]]++;}
    43         while(r<q[i].r) {res-=lnum[g[r]],rnum[g[r]]--;r++;}
    44         ans[q[i].id]=1LL*(q[i].l+1)*(n-q[i].r+2)-res;
    45     }rep(i,1,m) printf("%lld
    ",ans[i]);
    46 }
    View Code

    有结论之后的B题是bzoj 5016这道题的弱化版

    题意为:给定了两个区间$[l1,r1]$和$[l2,r2]$,求$sumlimits_{i=0}^{infty} get(l1,r1,i) imes get(l2,r2,i)$,其中$get(l,r,x)$表示$[l,r]$中$x$的数量

    思路:还是莫队,拆成四个区间容斥一下即可

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #include<map>
    10 #include<set>
    11 #define ll long long
    12 #define db double
    13 #define inf 2139062143
    14 #define MAXN 200100
    15 #define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i)
    16 #define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i)
    17 #define ren for(register int i=fst[x];i;i=nxt[i])
    18 #define pb(i,x) tot[i].push_back(x)
    19 #define pls(a,b) (a+b)%MOD
    20 #define mns(a,b) (a-b+MOD)%MOD
    21 #define mul(a,b) (1LL*(a)*(b))%MOD
    22 using namespace std;
    23 inline int read()
    24 {
    25     int x=0,f=1;char ch=getchar();
    26     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    27     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    28     return x*f;
    29 }
    30 int n,m,g[MAXN],bl[MAXN],lnum[MAXN],rnum[MAXN],sz;
    31 ll ans[MAXN],res;struct ask{int l,r,t,id;}q[MAXN];
    32 bool cmp(ask a,ask b){return bl[a.l]<bl[b.l]||(bl[a.l]==bl[b.l]&&a.r<b.r);}
    33 int main()
    34 {
    35     n=read(),sz=sqrt(n);rep(i,1,n) g[i]=read(),bl[i]=(i-1)/sz;g[n+1]=n+1;
    36     m=read();int l,r,x,y;rep(i,1,m)
    37     {
    38         l=read(),r=read(),x=read(),y=read();
    39         q[(i-1<<2)|1]=(ask){r,x,1,i};
    40         q[(i-1<<2)|2]=(ask){l-1,x,-1,i};
    41         q[(i-1<<2)|3]=(ask){r,y+1,-1,i};
    42         q[i<<2]=(ask){l-1,y+1,1,i};
    43     }
    44     m<<=2;sort(q+1,q+m+1,cmp);l=0,r=n+1;rep(i,1,m)
    45     {
    46         while(l<q[i].l) {l++;res+=rnum[g[l]],lnum[g[l]]++;}
    47         while(l>q[i].l) {res-=rnum[g[l]],lnum[g[l]]--;l--;}
    48         while(r>q[i].r) {r--;res+=lnum[g[r]],rnum[g[r]]++;}
    49         while(r<q[i].r) {res-=lnum[g[r]],rnum[g[r]]--;r++;}
    50         ans[q[i].id]+=res*q[i].t;
    51     }rep(i,1,m>>2) printf("%lld
    ",ans[i]);
    52 }
    View Code

    T3

    题目大意:

    有$n$条直线,求这些直线中所有两两交点中距离一定点$(x_0,y_0)$前$m$近的距离和

    思路:

    可以二分一个圆,判断圆内是否有$m$个交点,先求出直线和圆的交点

    则若在圆上存在$ABAB$的形式则有一个交点,其中$A,B$表示直线$a,b$与圆的交点

    可以使用树状数组类似数点来计算

    二分出半径后,按照靠左的交点排序后,遍历圆上的点,找出$l-r$这两个交点之间的其他直线的交点

    这样找出的两个直线一定是满足条件的,依次加入答案即可(为了方便使用set找着个区间

    (因为标程的精度锅了,所以用$cf$的形式读入

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #include<map>
    10 #include<set>
    11 #define ll long long
    12 #define db double
    13 #define inf 2139062143
    14 #define MAXN 100100
    15 #define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i)
    16 #define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i)
    17 #define ren for(register int i=fst[x];i;i=nxt[i])
    18 #define pb(i,x) vec[i].push_back(x)
    19 #define pls(a,b) (a+b)%MOD
    20 #define mns(a,b) (a-b+MOD[d])%MOD
    21 #define mul(a,b) (1LL*(a)*(b))%MOD
    22 using namespace std;
    23 inline int read()
    24 {
    25     int x=0,f=1;char ch=getchar();
    26     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    27     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    28     return x*f;
    29 }
    30 const db pi=acos(-1),eps=1e-6;
    31 int n,m,K,c[MAXN];db tx,ty,ans,k[MAXN],b[MAXN],a[MAXN],y[MAXN];
    32 struct Data{db x,y;int id;} g[MAXN];
    33 bool operator < (Data a,Data b) {return a.x<b.x;}
    34 #define fi first
    35 #define se second
    36 #define mp make_pair
    37 void mdf(int x,int val) {for(;x<=n;x+=x&-x) c[x]+=val;}
    38 int query(int x,int res=0) {for(;x;x-=x&-x) res+=c[x];return res;}
    39 int cheq(int res=0)
    40 {
    41     int l,r;rep(i,1,m)
    42     {
    43         l=lower_bound(y+1,y+m+1,g[i].x)-y-1;
    44         r=lower_bound(y+1,y+m+1,g[i].y)-y;
    45         res+=query(r)-query(l),mdf(r,1);
    46     }return res>=K;
    47 }
    48 db get(db k1,db k2,db b1,db b2) {return (b2-b1)/(k1-k2);}
    49 int main()
    50 {
    51     n=read(),tx=0.001*read(),ty=0.001*read();K=read();rep(i,1,n)
    52     {
    53         k[i]=0.001*read(),b[i]=0.001*read(),a[i]=atan(k[i]);
    54         if(tx*k[i]+b[i]>ty) a[i]+=pi/2;else a[i]-=pi/2;
    55     }
    56     db l=0,r=1e11,mid,d;for(;mid=(l+r)/2,l<r-eps;)
    57     {
    58         m=0;memset(c,0,sizeof(c));rep(i,1,n)
    59         {
    60             d=fabs(k[i]*tx-ty+b[i])/sqrt(k[i]*k[i]+1);if(d>mid) continue;
    61             d=acos(d/mid);g[++m]=(Data){a[i]-d,a[i]+d,0};
    62             if(g[m].x<=-pi) g[m].x+=2*pi;if(g[m].y>pi) g[m].y-=2*pi;
    63             if(g[m].x>g[m].y) swap(g[m].x,g[m].y);y[m]=g[m].y;
    64         }
    65         sort(y+1,y+m+1);sort(g+1,g+m+1);if(cheq()) r=mid;else l=mid;
    66     }mid=r;
    67     set <pair<db,int> > s;set <pair<db,int> > ::iterator it;
    68     m=0;rep(i,1,n)
    69     {
    70         d=fabs(k[i]*tx-ty+b[i])/sqrt(k[i]*k[i]+1);if(d>mid) continue;
    71         d=acos(d/mid);g[++m]=(Data){a[i]-d,a[i]+d,i};
    72         if(g[m].x<=-pi) g[m].x+=2*pi;if(g[m].y>pi) g[m].y-=2*pi;
    73         if(g[m].x>g[m].y) swap(g[m].x,g[m].y);
    74     }sort(g+1,g+m+1);int tot=0;
    75     rep(i,1,m) 
    76     {
    77         it=s.lower_bound(mp(g[i].x,0));
    78         for(;it!=s.end()&&it->fi<=g[i].y;++it,++tot)
    79         {
    80             if(tot==K) break;l=get(k[g[i].id],k[it->se],b[g[i].id],b[it->se]);
    81             r=k[g[i].id]*l+b[g[i].id];ans+=sqrt((tx-l)*(tx-l)+(ty-r)*(ty-r));
    82         }
    83         s.insert(mp(g[i].y,g[i].id));if(tot==K) break;
    84     }
    85     printf("%.10lf
    ",ans);
    86 }
    View Code
  • 相关阅读:
    greenplum 常用整理
    postgresql 常用整理
    数据源整理
    hive 以like方式建表(携带表结构)
    kudu 常用整理
    mysql常用整理
    Linux查看文件内容的常用方式(more,less,head,tail,cat)
    python2.7 安装docx错误
    python2.7 安装搜索引擎错误
    mysql数据库安装错误
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/10640476.html
Copyright © 2020-2023  润新知