[考试反思]0404省选模拟62:判断

经典的遇到原题就乱了阵脚系列。

其实也并不是,听了全城的各种喇叭响了几分钟,整个人是懵的,也就突然不想写暴力了。

感觉自己像个弱智。然而考后就把暴力补上了。

写两个签到级的暴力就能排第$4$啊喂。。。。

老老实实打暴力。别说了,正解扔一旁,暴力先敬上。

T1:Fable

大意:求冒泡排序$k$轮后所得序列。$nle 2 imes 10^5$

每次考虑前$k+1$位,最小的一定出现在最前面,然后删掉它继续向后考虑就行。用个堆维护。

我的弱智想法是:每个点前面若有$x$个比它大的点,那么它最终的位置就是它往后第$k-x$个比它大的的下标$-k$。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define S 400005
 4 int bgr[S],a[S],r[S],n,k,t[S],pos[S],ans[S],pc; vector<int>ve[S];
 5 void add(int x){for(;x;x^=x&-x)t[x]++;}
 6 int ask(int x,int a=0){for(;x<=n;x+=x&-x)a+=t[x];return a;}
 7 int v[S<<2],lz[S<<2];
 8 #define lc p<<1
 9 #define rc lc|1
10 #define md (L+R>>1)
11 void down(int p){if(lz[p])lz[lc]+=lz[p],lz[rc]+=lz[p],v[lc]+=lz[p],v[rc]+=lz[p],lz[p]=0;}
12 void Add(int r,int p=1,int L=1,int R=n*2){if(!r)return;
13     if(R<=r){v[p]++;lz[p]++;return;}
14     down(p); Add(r,lc,L,md); if(r>md)Add(r,rc,md+1,R); v[p]=min(v[lc],v[rc]);
15 }
16 int ask_val(int P,int p=1,int L=1,int R=2*n){
17     if(L==R)return v[p];
18     down(p); return P<=md?ask_val(P,lc,L,md):ask_val(P,rc,md+1,R);
19 }
20 int ask_pos(int V,int p=1,int L=1,int R=2*n){
21     if(L==R)return L;
22     down(p); return v[lc]<=V?ask_pos(V,lc,L,md):ask_pos(V,rc,md+1,R);
23 }
24 int main(){
25     cin>>n>>k;
26     for(int i=1;i<=n;++i)scanf("%d",&a[i]),r[i]=a[i];
27     sort(r+1,r+1+n);
28     for(int i=1;i<=n;++i)a[i]=lower_bound(r+1,r+1+n,a[i])-r;
29     for(int i=1;i<=n;++i)add(a[i]),bgr[i]=ask(a[i]+1);
30     for(int i=n+1;i<=n+n;++i)a[i]=i,Add(i-1);
31     for(int i=n;i;--i)ve[a[i]].push_back(i);
32     for(int j=n;j;--j)for(int q=0,i;i=q<ve[j].size()?ve[j][q]:0;++q)Add(i-1),ans[ask_pos(ask_val(i)-max(0,k-bgr[i]))-k]=r[a[i]];
33     for(int i=1;i<=n;++i)printf("%d
",ans[i]);
34 }
View Code

T2:Fiend

大意:给定$L_i,R_i$。求所有$L_ile p_i le R_i$的排列中,奇排列与偶排列数量的大小关系。$T le 500,n le 10^5$

哦,原来是行列式定义。

本体特殊性质在于:每行矩阵$1$的是一段连续区间。

那么按照端点双关键字排序后,枚举左端点。

如果不存在主元,显然为$0$。否则,所有左端点与它一致的区间,左端点重置为其右端点$+1$

启发式合并$set$,$O(Tnlog^2n)$

可并堆。左偏树。$O(Tnlogn)$

问题在于求交换了几次,所以记录一个原来的行号判断是否一致,不一致就交换。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define S 100005
 4 int lc[S],rc[S],dt[S],pc,val[S],id[S],n,re[S];
 5 int newp(int X,int I){val[++pc]=X;id[pc]=I;re[I]=pc;dt[pc]=1;lc[pc]=rc[pc]=0;return pc;}
 6 int  merge(int a,int b){
 7     if(!a||!b)return a|b;
 8     if(val[a]>val[b])swap(a,b);
 9     rc[a]=merge(rc[a],b);
10     if(dt[rc[a]]>dt[lc[a]])swap(lc[a],rc[a]);
11     dt[a]=dt[rc[a]]+1; return a;
12 }
13 struct node{
14     int rt;
15     void ins(int X,int I){rt=merge(rt,newp(X,I));}
16     void pop(){rt=merge(lc[rt],rc[rt]);}
17 }N[S];
18 int main(){int t;cin>>t;while(t--){
19     cin>>n; int op=1;
20     for(int i=1,l,r;i<=n;++i)scanf("%d%d",&l,&r),N[l].ins(r,i);
21     for(int i=1;i<=n;++i)if(!N[i].rt){puts("D");goto F;}
22         else{
23             if(id[N[i].rt]!=i)op^=1,re[id[re[i]]=id[N[i].rt]]=re[i];
24             int z=val[N[i].rt];N[i].pop();
25             if(val[N[i].rt]==z){puts("D");goto F;}
26             N[z+1].rt=merge(N[i].rt,N[z+1].rt);
27         }
28     puts(op?"Y":"F");F:pc=0;memset(N,0,sizeof N);
29 }}
View Code

T3:Flair

大意:$n$个物品,每个都有$p$概率选中,代价为个数。$m$种面额的钱。不设找零,求期望最少浪费多少钱。$n le 10^9,m le 100,c_ic_j le 10000$

一猜就是《小凯的疑惑》的结论。但是不保证互质。故可以求出$G=gcd(c)$。

对于$i>10000$,那么代价就是$(G-i mod G) mod G$

所以说,选中个数可以对$G$取模。那么只要做个生成函数的快速幂(循环卷积)就行。

然后对于$i<10000$做个背包就没了。

毒瘤玩意要写$MTT$。重新复习,强行弄了个$4FFT$的跑得还贼慢。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int mod=1000000007,_=32767,S=66666;
 4 #define Pi 3.141592653589793238L
 5 int n,m,p,C[111],rev[S],len=1,F[S],G,f[S],ans,bp[S],iv[S],B[S];
 6 int gcd(int a,int b){return b?gcd(b,a%b):a;}
 7 int mo(int x){return x>=mod?x-mod:x;}
 8 struct cp{
 9     double r,i;
10     cp(double x=0,double y=0){r=x;i=y;}
11     cp operator+(cp x){return cp(r+x.r,i+x.i);}
12     cp operator-(cp x){return cp(r-x.r,i-x.i);}
13     cp operator*(cp x){return cp(r*x.r-i*x.i,r*x.i+i*x.r);}
14 }x,y,Q[S],E[S],R[S];vector<cp>w[2][19];
15 void pt(int*x){for(int i=0;i<len;++i)cout<<x[i]<<' ';puts("");}
16 void sat(int x){
17     len=1;while(len<=x)len<<=1;
18     for(int i=1;i<len;++i)rev[i]=rev[i>>1]>>1|(i&1?len>>1:0);
19 }
20 void FFT(cp*a,int op){
21     for(int i=0;i<len;++i)if(rev[i]>i)swap(a[rev[i]],a[i]);
22     for(int i=1,b=0;i<len;i<<=1,b++)for(int j=0;j<len;j+=i<<1)for(int k=j;k<j+i;++k)
23         x=a[k],y=a[k+i]*w[op][b][k-j],a[k]=x+y,a[k+i]=x-y;
24     if(!op)for(int i=0;i<len;++i)a[i].r/=len,a[i].i/=len;
25 }
26 long long r(double x){return (long long)(x+0.5)%mod;}
27 void MTT(int*a,int*b,int*c){
28     for(int i=0;i<len;++i)Q[i]=cp(a[i]>>15,a[i]&_),E[i]=cp(b[i]>>15,b[i]&_);
29     FFT(Q,1);FFT(E,1);
30     for(int i=0;i<len;++i)R[i]=cp(Q[i].r/2,Q[i].i/2);
31     for(int i=0,o=0;i<len;++i,o=len-i)
32         Q[i]=cp(R[i].r+R[o].r,R[i].i-R[o].i)*E[i],
33         E[i]=cp(R[i].i+R[o].i,R[o].r-R[i].r)*E[i];
34     FFT(Q,0);FFT(E,0);
35     for(int i=0;i<len;++i)c[i]=((r(Q[i].r)<<30)+(r(Q[i].i+E[i].r)<<15)+r(E[i].i))%mod;
36 }
37 void Mul(int*a,int*b,int*c){
38     MTT(a,b,c);
39     for(int i=G;i<len;++i)c[i%G]=mo(c[i%G]+c[i]),c[i]=0;
40 }
41 int qp(int b,int t,int a=1){for(;t;t>>=1,b=1ll*b*b%mod)if(t&1)a=1ll*a*b%mod;return a;}
42 int main(){iv[1]=1;//freopen("ex_flair2.in","r",stdin);
43     for(int i=0;i<17;++i)w[0][i].resize(1<<i),w[1][i].resize(1<<i);
44     for(int i=0,x=1;i<17;++i,x<<=1)for(int j=0;j<x;++j)
45         w[0][i][j]=cp(cos(Pi/x*j),-sin(Pi/x*j)),w[1][i][j]=cp(cos(Pi/x*j),sin(Pi/x*j));
46     for(int i=2;i<10086;++i)iv[i]=mod-1ll*mod/i*iv[mod%i]%mod;
47     int t;cin>>t;while(t--){
48         cin>>n>>m>>p; G=ans=0;
49         for(int i=1;i<=m;++i)scanf("%d",C+i),G=gcd(G,C[i]);
50         F[0]=100-p;F[1]=p; B[0]=f[0]=bp[0]=1; sat(G<<1);
51         for(int i=n;i;i>>=1,Mul(F,F,F))if(i&1)Mul(f,F,f);
52         for(int i=1;i<G;++i)ans=(ans+1ll*(G-i)*f[i])%mod;
53         for(int i=0;i<=10000&&i<=n;++i)if(bp[i])for(int j=1;j<=m;++j)bp[i+C[j]]=1;
54         for(int i=1;i<=10000&&i<=n;++i)B[i]=B[i-1]*(n+1ll-i)%mod*iv[i]%mod;
55         int l,z=qp(p,min(n,10000))*1ll*qp(100-p,n-min(n,10000))%mod;
56         for(int i=20000;i>10000||i>n;--i)if(bp[i])l=i;
57         for(int i=min(10000,n);i;--i){
58             if(bp[i])l=i;
59             ans=(ans+(l-i-(G-i%G)%G)*1ll*B[i]%mod*z)%mod;z=1ll*z*iv[p]%mod*(100-p)%mod;
60         }cout<<ans<<endl;
61         memset(F,0,sizeof F);memset(f,0,sizeof f);memset(bp,0,sizeof bp);
62     }
63 }
View Code
原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/12634791.html