• [考试反思]0509省选模拟92:警示


    同一种低错能犯不知道多少次。就应该有个人在我每次弱智的时候骂我一顿不然真是不长脑子。

    $50$分$50$分的挂。。。(虽说牛更惨直接把绿框挂丢了

    莫队排序$x.l/B<x.l/B$。$y$呢?

    然后就直接$T$成暴力。亏得我还写了对拍,没有试大测试点。(暴力跑不出来)

    之前就有一次因为对拍没有试大数据爆炸了,

    但愿能长记性吧。。。

    本来是拿下构造剩下暴力写满的。构造题有多解但是最开始没有$spj$我人都傻了

    (最近构造题好多。貌似终于发现了第一个我比较擅长的题型。。。或许也不好说。。。菜死了

    耽误了不少时间而且把心态弄得有点炸。。。$T1$那玩意都做烂了还没想出正解的确可能受到了一定影响

    再说了。。。根号算法就那么几个咋每次都用不好。。。

    反正状态不是很好。。。下次还要调整啊。。。

    T1:Mansion

    大意:有$n$个点,每个点有权值$a_i,b_i$。多次询问$maxlimits_{i=vl}^{vr} (sumlimits_{j=l}^{r} b_j [a_j = i] ) $。$n,m,q le 1.5 imes 10^5$

    被牛嘲讽了。

    是个类似于区间众数的问题。这种问题最低复杂度也就是$O(n^{1.5})$了

    学过的根号就那么几种,所以不难想到莫队。维护线段树即可。复杂度是$O(sqrt{n} log n)$的。

    然后在莫队中,修改次数是$O(nsqrt{n})$的但是查询次数是$O(n)$的,

    所以根号平摊一下,分块$O(1)$修改$O(sqrt{n})$查询就行了。

    然而不支持删除。那就把莫队回滚一下。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int S=150005,B=400;
     4 struct Qs{int l,r,vl,vr,o;friend bool operator<(Qs x,Qs y){return x.l/B!=y.l/B?x.l/B<y.l/B:x.r<y.r;}}Q[S];
     5 int n,m,q,a[S],b[S],p[S],t;long long w[S],c[S],ans[S],wv[S],cv[S];
     6 #define lc p<<1
     7 #define rc p<<1|1
     8 #define md (L+R>>1)
     9 void add(int x,int v,int op){
    10     if(op)p[++t]=x,wv[t]=w[x],cv[t]=c[x/B];
    11     w[x]+=v; c[x/B]=max(c[x/B],w[x]);
    12 }
    13 long long ask(int l,int r,long long a=0){
    14     if(l/B==r/B)for(int i=l;i<=r;++i)a=max(a,w[i]);
    15     else{
    16         for(int i=l;i<l/B*B+B;++i)a=max(a,w[i]);
    17         for(int i=r;i>=r/B*B;--i)a=max(a,w[i]);
    18         for(int i=l/B+1;i<r/B;++i)a=max(a,c[i]);
    19     }return a;
    20 }
    21 void clear(){while(t)w[p[t]]=wv[t],c[p[t]/B]=cv[t],t--;}
    22 int main(){//freopen("1.in","r",stdin);freopen("1.out","w",stdout);
    23     scanf("%d%d%d",&n,&m,&q);
    24     for(int i=1;i<=n;++i)scanf("%d",&a[i]);
    25     for(int i=1;i<=n;++i)scanf("%d",&b[i]);
    26     for(int i=1;i<=q;++i)scanf("%d%d%d%d",&Q[i].l,&Q[i].r,&Q[i].vl,&Q[i].vr),Q[i].o=i;
    27     Q[0].l=-B; sort(Q+1,Q+1+q);
    28     for(int l=1,r=0,i=1;i<=q;++i){
    29         if(Q[i].l/B!=Q[i-1].l/B){
    30             l=Q[i].l/B*B+B;r=l-1;
    31             for(int i=1;i<=m;++i)w[i]=c[i]=0;
    32         }
    33         if(Q[i].l/B==Q[i].r/B){
    34             for(int j=Q[i].l;j<=Q[i].r;++j)add(a[j],b[j],1);
    35             ans[Q[i].o]=ask(Q[i].vl,Q[i].vr);
    36             clear(); continue;
    37         }
    38         while(r<Q[i].r)++r,add(a[r],b[r],0);
    39         while(l>Q[i].l)--l,add(a[l],b[l],1);
    40         ans[Q[i].o]=ask(Q[i].vl,Q[i].vr);
    41         clear(); l=Q[i].l/B*B+B;
    42     }for(int i=1;i<=q;++i)printf("%lld
    ",ans[i]);
    43 }
    View Code

    T2:Permutation

    大意:给定一个陪列,每次操作可以选定一些元素,被选中的元素放到所有没选中的元素之后,且选中的和未选中的元素内部相对顺序不变。

    要求最小化变为元排列的步数以及构造方案。$n le 5 imes 10^4$

    对于任意两个元素$a,b$,不妨设$a<b$

    若在一开始$a$就在$b$前面,那么在每次操作中,两个数所经历的是否被选中的状态可以完全相同。

    如果被选中是$1$不被选中是$0$,那么对于每个数经历的操作会形成一个$01$串,如$w_a$(注意是针对数说的,而不是针对下标)

    若$a<b,ia<ib$则$w_a$可以等于$w_b$

    然后考虑如果$w_a eq w_b$有哪些可能。

    如果操作序列不完全相同的话,最终两元素的相对位置由 最后一次两者选中状态不同的那次操作中谁被选中了 决定。

    具体而言,如果最后一次不同是在操作$i$,则若$a<b$则$w_{a,i} = 0 ,w_{b,i}=1$

    我们发现这样的话,我们把二进制串理解成二进制数的话(后面的操作为高位前面的操作是低位)

    那么就是说,若$a<b$且$w_a eq w_b$则$w_a < w_b$

    整理得到对于任意$a<b$,若$p_a < p_b$则$w_a le w_b$,否则$w_a < w_b$

    这样我们就得到了$n^2$个限制关系。没法做。

    考虑到谁在谁前面 这种关系是有传递性的,最后我们要构造的是元排列,那么只要$1$在$2$前面,$2$在$3$前面。。。$n-1$在$n$前面就足够了

    不再需要$1$在$3$前面这种限制。那么现在就只剩下了$n-1$条限制。整理如下:

    $0 le w_1 <= w_2 <= w_3 <= ... <= w_n <2^{ans}$

    其中的$<=$可能被替换为$<$或$le$。为了最小化$ans$我们一定会在所有可以和前面一个值取等的地方取等,不能取等就只$+1$

    显然是最优的。这样就得到了所有的$w$。$ans$和方案也就显然了。

     1 #include<cstdio>
     2 #define S 55555
     3 int p[S],ip[S],n,ord,ans,v[S],op,q1[S],q2[S],t1,t2;
     4 int main(){
     5     scanf("%d%d",&n,&op);
     6     for(int i=1;i<=n;++i)scanf("%d",&p[i]),ip[p[i]]=i;
     7     for(int i=n-1;i;--i)v[i]=ip[i]>ip[i+1]?++ord:ord;
     8     while(1<<ans<=ord)ans++;
     9     printf("%d
    ",ans);
    10     if(!op)return 0;
    11     for(int i=1;i<=n;++i)v[i]=ord-v[i];
    12     for(int i=1;i<=n;++i)printf("%d ",p[i]);puts("");
    13     while(ans--){
    14         t1=t2=0;
    15         for(int i=1;i<=n;++i)if(v[p[i]]&1)q1[++t1]=p[i],v[p[i]]>>=1;
    16             else q2[++t2]=p[i],v[p[i]]>>=1;
    17         for(int i=1;i<=t2;++i)printf("%d ",p[i]=q2[i]);
    18         for(int i=1;i<=t1;++i)printf("%d ",p[i+t2]=q1[i]); puts("");
    19     }
    20 }
    View Code

    T3:Grid Game

    由于太菜咕掉了。去看牛神的博客吧。

  • 相关阅读:
    暗通道先验去雾算法及其几何意义的解释
    几种去雾算法介绍
    大气散射模型的推导
    散射介质环境中偏振成像图像的去散射方法
    最近的笔面试题知识整理一
    了解 Web Service
    数梦工厂笔试题回顾一----finally在return之后执行还是之前?
    Struts2的配置文件的加载
    Struts2中Action配置
    struts.xml的语法
  • 原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/12860491.html
Copyright © 2020-2023  润新知