zoukankan      html  css  js  c++  java
  • [考试反思]0525省选模拟105:搁浅

    不知道为啥当时咕了,然后咕了太久了,回来写反思的时候已经没有反思了。

    反正我好菜啊,直接写题解吧。

    T1:数据结构

    大意:维护序列,单点修改,查询某个区间$[l,r]$的区间和的历史最小值。$n,q le 10^5$

    $KD-tree$又日爆一切二维几何了。

    牛神又日爆一切$KD-tree$题了。

    矩形加,历史最小值,简单维护。$O(qsqrt{n})$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define S 400005
     4 #define ll long long
     5 int cmp,op[S],x[S],y[S],n,m,a[S],qc,mxl[S],mnr[S],mxr[S],mnl[S];
     6 ll w[S],lz[S],mnlz[S],pre[S],mn[S];
     7 struct P{int l,r;}Q[S],T[S];
     8 ll cal(P x){return cmp?1000000000ll*x.l+x.r:1000000000ll*x.r+x.l;}
     9 bool operator<(P x,P y){return cal(x)<cal(y);}
    10 #define lc p<<1
    11 #define rc lc|1
    12 #define fa p>>1
    13 void build(int p,int l,int r){
    14     if(l>r)return;
    15     cmp^=1; int md=l+r>>1;
    16     nth_element(Q+l,Q+md,Q+r+1);
    17     T[p]=Q[md];mn[p]=w[p]=pre[mxr[p]=mnr[p]=T[p].r]-pre[(mnl[p]=mxl[p]=T[p].l)-1];
    18     build(lc,l,md-1);build(rc,md+1,r);cmp^=1;
    19     mnr[fa]=min(mnr[fa],mnr[p]); mxl[fa]=max(mxl[fa],mxl[p]);
    20     mxr[fa]=max(mxr[fa],mxr[p]); mnl[fa]=min(mnl[fa],mnl[p]);
    21 }
    22 void down(int p){
    23     if(!lz[p]&&!mnlz[p])return;
    24     mn[lc]=min(mn[lc],w[lc]+mnlz[p]);mn[rc]=min(mn[rc],w[rc]+mnlz[p]);
    25     w[lc]+=lz[p];w[rc]+=lz[p];
    26     mnlz[lc]=min(mnlz[lc],lz[lc]+mnlz[p]);mnlz[rc]=min(mnlz[rc],lz[rc]+mnlz[p]);
    27     lz[lc]+=lz[p];lz[rc]+=lz[p];
    28     lz[p]=mnlz[p]=0;
    29 }
    30 void add(int L,int v,int p){
    31     if(mxr[p]<L||mnl[p]>L)return;
    32     if(mxl[p]<=L&&mnr[p]>=L){lz[p]+=v;mnlz[p]=min(mnlz[p],lz[p]);w[p]+=v;mn[p]=min(mn[p],w[p]);return;}
    33     if(T[p].l<=L&&T[p].r>=L)w[p]+=v,mn[p]=min(mn[p],w[p]);
    34     down(p);add(L,v,lc);add(L,v,rc);
    35 }
    36 ll ask(int l,int r,int p){
    37     if(T[p].l==l&&T[p].r==r)return mn[p];
    38     cmp^=1;down(p);return ask(l,r,cal((P){l,r})<cal(T[p])?lc:rc);
    39 }
    40 int main(){
    41     scanf("%d%d",&n,&m);
    42     for(int i=1;i<=n;++i)scanf("%d",&a[i]),pre[i]=pre[i-1]+a[i];
    43     for(int i=1;i<=m;++i){
    44         scanf("%d%d%d",&op[i],&x[i],&y[i]);
    45         if(op[i]==2)Q[++qc]=(P){x[i],y[i]};
    46     }
    47     build(1,1,qc);
    48     for(int i=1;i<=m;++i)
    49         if(op[i]==2)cmp=0,printf("%lld
    ",ask(x[i],y[i],1));
    50         else add(x[i],y[i]-a[x[i]],1),a[x[i]]=y[i];
    51 }
    View Code

    T2:B

    大意:给定$01$串$S,T$,$S_i=[ai+b le c (mod n)]$。$S$是循环的。求$S$从第$p$位开始能和$T$匹配几位,或者单点修改$T$。$|T| le 10^5,others le 10^9$

    如果$T_i=0$那么我们要查的就是$[0 le a(i+p)+b le c (mod n)]$,也就是说$[-ap le ai+b le c-ap (mod n)]$

    所以只与$ai+b$有关在最开始的时候插入树状数组然后查询的时候只与$p$有关查询上述区间即可。

    $T_i=1$同理。修改的话只要在树状数组里一删一加就行了。

     1 #include<cstdio>
     2 #define S 6000007
     3 int n,m,b,c,q;char t[S];long long a;
     4 struct hash_map{
     5     int fir[S],l[S],to[S],v[S],ec;
     6     int&operator[](int x){ int r=x%S;
     7         for(int i=fir[r];i;i=l[i])if(to[i]==x)return v[i];
     8         l[++ec]=fir[r];fir[r]=ec;to[ec]=x;return v[ec];
     9     }
    10 };
    11 struct Fenwick_Tree{
    12     hash_map t;
    13     void add(int p,int v=1){for(;p<=n;p+=p&-p)t[p]+=v;}
    14     int ask(int p,int a=0){for(;p;p^=p&-p)a+=t[p];return a;}
    15     int query(int l,int r){return l<=r?ask(r)-ask(l-1):ask(n)-(ask(l-1)-ask(r));}
    16 }T[2];
    17 int mo(long long x){return (x%n+n)%n+1;}
    18 int main(){
    19     scanf("%d%lld%d%d%d%s%d",&n,&a,&b,&c,&m,t,&q);
    20     for(int i=0;i<m;++i)t[i]-=48,T[t[i]].add(mo(a*i));
    21     for(int _=1,o,p;_<=q;++_){
    22         scanf("%d%d",&o,&p);
    23         if(o==2)T[t[p]].add(mo(a*p),-1),T[t[p]^=1].add(mo(a*p));
    24         else printf("%d
    ",T[0].query(mo(-a*p-b+c),mo(-a*p-b-1))+T[1].query(mo(-a*p-b),mo(-a*p-b+c-1)));
    25     }
    26 }
    View Code

    T3:C

    大意:树,随机点出发,每个点有一个$01$状态,每一次会随机选择一个点,沿树边走到那个点并将其权值取反。所有点权值都相同时结束。求期望经过的总距离。$n le 10^5$

    期望线性性,对每个点考虑贡献。

    这是完全随机的游走,从每个点出发走到的点的距离期望是确定的可以直接换根$dp$得到。

    然后所有点之间的区别就只剩下了:当前权值。状态的差异还有树上有几个权值为$1$的点。

    根据这个设出$dp$。

    这个东西,首先状态定义是:走到当前点,游戏未结束,此时当前点被经过的期望次数。要时刻注意你考虑的是一个点而不是一种权值的贡献

    两个转移是出边和。前面的那个$frac{1}{n}$的常量是分别跟着后面系数为$frac{1}{n}$

    分别讨论选中的是当前点,还是权值为$01$的点(第一个不包含于后两个)

    所谓的边界情况是,$val_{0,0}=val_{0,1}=val_{n,0}=val{n,1}=0$。

    然后$val_{n-1,0}$选自己会转移到$val_{n,1}$,不满足含义中“游戏仍在继续”的限制,所以没有$frac{1}{n}$的系数。$val_{1,1}$同理。

    至此我们考虑了游戏仍在继续的情况(游戏不再继续你自然就不会再走)。没有考虑的就是随机出发所走的第一步,所以所有点的期望经过次数还要加$frac{1}{n}$

    然后并不需要根据方程在$i=n-1$处列额外的方程,这东西有明显的对称性,所以显然有$val_{n-1,0}=val_{1,1},val_{n-1,1}=val_{1,0}$。

    所以就解方程就行了。爆写式子有点细节。。。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int S=1e5+5,mod=1e9+7;
     4 int fir[S],l[S],to[S],ec,n,d[S],sz[S],inv[S],v11,v10,cnt,ans;char s[S];
     5 void link(int a,int b){l[++ec]=fir[a];fir[a]=ec;to[ec]=b;}
     6 int mo(int x){return x>=mod?x-mod:x;}
     7 void dfs(int p){sz[p]=1;for(int i=fir[p],y;y=to[i];i=l[i])dfs(y),sz[p]+=sz[y],d[p]=mo(d[p]+mo(d[y]+sz[y]));}
     8 void DFS(int p){for(int i=fir[p],y;y=to[i];i=l[i])d[y]=(0ll+d[p]-sz[y]+n-sz[y]+mod)%mod,DFS(y);}
     9 int qp(int b,int t=mod-2,int a=1){for(;t;t>>=1,b=1ll*b*b%mod)if(t&1)a=1ll*a*b%mod;return a;}
    10 int gcd(int a,int b){return b?gcd(b,a%b):a;}
    11 struct coef{
    12     int c0,c1,c;
    13     coef operator+(coef x){return (coef){mo(c0+x.c0),mo(c1+x.c1),mo(c+x.c)};}
    14     coef operator-(coef x){return (coef){mo(c0+mod-x.c0),mo(c1+mod-x.c1),mo(c+mod-x.c)};}
    15     coef operator*(long long x){return (coef){c0*x%mod,c1*x%mod,c*x%mod};}
    16     coef operator-(int x){return (coef){c0,c1,mo(c+mod-x)};}
    17     int cal(){return (1ll*c0*v10+1ll*c1*v11+c)%mod;}
    18 }c[S][2];
    19 int main(){
    20     scanf("%d%s",&n,s+1); inv[1]=1;
    21     for(int i=2;i<=n;++i)inv[i]=mod-mod/i*1ll*inv[mod%i]%mod;
    22     for(int i=2,a;i<=n;++i)scanf("%d",&a),link(a,i);
    23     dfs(1);DFS(1);
    24     c[1][0].c0=c[1][1].c1=1;
    25     for(int i=1;i<n-1;++i)
    26         c[i+1][1]=(c[i][1]*n-c[i-1][1]*(i-1)-c[i-1][0]-(i!=1))*inv[n-i],
    27         c[i+1][0]=(c[i][0]*n-c[i-1][0]*i-c[i+1][1]-1)*inv[n-i-1];
    28     c[n][0]=c[1][1]-c[n-1][0];
    29     c[n][1]=c[1][0]-c[n-1][1];
    30     if(!c[n][1].c0)swap(c[n][0],c[n][1]);else c[n][0]=c[n][0]*qp(c[n][0].c0)*c[n][1].c0-c[n][1];
    31     v11=mod-1ll*qp(c[n][0].c1)*c[n][0].c%mod,v10=mo(mod+mod-1ll*v11*c[n][1].c1%mod-c[n][1].c)*1ll*qp(c[n][1].c0)%mod,cnt=0,ans=0;
    32     for(int i=1;i<=n;++i)cnt+=s[i]-48;
    33     for(int i=1;i<=n;++i)ans=(ans+(c[cnt][s[i]-48].cal()+inv[n])*1ll*d[i])%mod;
    34     printf("%lld
    ",ans*1ll*qp(n)%mod);
    35 }
    View Code
  • 相关阅读:
    如何在Kubernetes集群动态使用 NAS 持久卷
    如何在Kubernetes集群动态使用 NAS 持久卷
    谷歌浏览器报错Unchecked runtime.lastError: The message port closed before a response was received.。
    优化信息流很麻烦?三招教你轻松搞定
    优化信息流很麻烦?三招教你轻松搞定
    java多线程
    java多线程
    酷狗音乐快速转换MP3格式的方法
    Golang项目部署
    解析HTML、JS与PHP之间的数据传输
  • 原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/13046667.html
Copyright © 2011-2022 走看看