zoukankan      html  css  js  c++  java
  • 十二省联考

    (upd:字符串问题AC)

    (upd:字符串问题写了80分)

    太菜了做不到满分啊……以后再看吧。

    异或粽子:

    正常人都是可持久化Trie一眼秒(我是弱智)

    #include<iostream>
    #include<cstdio>
    #include<queue>
    using namespace std;
    typedef long long i64;
    const int N=7e5+5;
    const int D=64;
    const int S=N*D;
    
    int cnt,c[S][2],z[S];
    i64 a[N],s[N];
    int f[N];
    struct inf{
        i64 s;
        int x; 
        bool operator<(const inf a)const{
            return s<a.s;
        }
    };
    priority_queue<inf>q;
    
    int ins(i64 x,int v){
        int r,u,i;
        i64 t;
        r=u=++cnt;
        z[u]=z[v]+1;
        for(i=D-1;i>=0;i--){
            t=(x>>i)&1;
            c[u][t^1]=c[v][t^1];
            ++cnt;
            c[u][t]=cnt;
            u=cnt;
            v=c[v][t];
            z[u]=z[v]+1;
        }
        return r;
    }
    
    int dlt(i64 x,int v){
        int r,u,i;
        i64 t;
        if(z[v]==1)return 0;
        r=u=++cnt;
        z[u]=z[v]-1;
        for(i=D-1;i>=0;i--){
            t=(x>>i)&1;
            c[u][t^1]=c[v][t^1];
            if(z[c[v][t]]==1)
                break;
            ++cnt;
            c[u][t]=cnt;
            u=cnt;
            v=c[v][t]; 
            z[u]=z[v]-1;
        }
        return r;
    }
    
    i64 slv(i64 x,int v){
        i64 s=0,t;
        int i;
        for(i=D-1;i>=0;i--){
            t=((x>>i)&1)^1;
            if(c[v][t]){
                s+=t<<i;
                v=c[v][t];
            }
            else{
                s+=(t^1)<<i;
                v=c[v][t^1];
            }
        }
        return s;
    }
    
    int main()
    {
        int n,m,i,v;
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            a[i]=a[i]^a[i-1];
            f[i]=ins(a[i-1],f[i-1]);
            s[i]=slv(a[i],f[i]);
            q.push((inf){a[i]^s[i],i});
        }
        i64 ans=0;
        for(i=1;i<=m;i++){
            v=q.top().x;
            ans+=a[v]^s[v];
            q.pop();
            f[v]=dlt(s[v],f[v]);
            if(f[v]){
                s[v]=slv(a[v],f[v]);
                q.push((inf){a[v]^s[v],v});
            }
        }
        printf("%lld",ans);
        return 0;
    }

    字符串问题:

    SA+树套树区间连边,内层树可以用后缀代替。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    using namespace std;
    typedef long long i64;
    const int N=2e5+5;
    const int D=20;
    const int S=7e6+6;
    const int M=2e7+7;
    
    char s[N];
    int t1[N],t2[N],c[S];
    int sa[N],rk[N],ht[N];
    
    int lg2[N];
    int gr[N][D];
    
    void gtsa(int n,int m){
        int *x=t1,*y=t2;
        int i,j,p=0;
        for(i=0;i<=m;i++)
            c[i]=0;
        for(i=1;i<=n;i++)
            ++c[x[i]=s[i]];
        for(i=1;i<=m;i++)
            c[i]+=c[i-1];
        for(i=n;i;i--)
            sa[c[x[i]]--]=i;
        for(j=1;j<=n&&p<n;j<<=1){
            p=0;
            for(i=n-j+1;i<=n;i++)
                y[++p]=i;
            for(i=1;i<=n;i++)
                if(sa[i]>j)
                    y[++p]=sa[i]-j;
            for(i=0;i<=m;i++)
                c[i]=0;
            for(i=1;i<=n;i++)
                ++c[x[y[i]]];
            for(i=1;i<=m;i++)
                c[i]+=c[i-1];
            for(i=n;i;i--)
                sa[c[x[y[i]]]--]=y[i];
            swap(x,y);
            x[sa[1]]=1;
            p=1;
            for(i=2;i<=n;i++)
                x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+j]==y[sa[i-1]+j]?p:++p;
            m=p;
        }
        for(i=1;i<=n;i++)
            rk[sa[i]]=i;
        p=0;
        for(i=1;i<=n;i++){
            j=sa[rk[i]-1];
            if(p)--p;
            while(s[i+p]==s[j+p])
                ++p;
            ht[rk[i]]=p;
        }
        memset(gr,0,sizeof(gr));
        for(i=1;i<=n;i++)
            gr[i][0]=ht[i];
        for(j=1;j<=lg2[n];j++)
            for(i=1;i+(1<<j)-1<=n;i++)
                gr[i][j]=min(gr[i][j-1],gr[i+(1<<j-1)][j-1]);
    }
    
    i64 f[S];
    int w[S];
    int l[S],e[M],x[M];
    int cnt,ecnt;
    
    void pshe(int u,int v){
        ++ecnt;x[ecnt]=l[u];l[u]=ecnt;e[ecnt]=v;
    }
    
    i64 clc(int v){
        if(c[v]==2)return f[v];
        c[v]=1;
        f[v]=0;
        for(int i=l[v];i;i=x[i]){
            if(c[e[i]]==1){
                f[v]=-1;
                c[v]=2;
                return f[v];
            }
            else{
                if(clc(e[i])==-1){
                    f[v]=-1;
                    return f[v];
                }
                f[v]=max(f[v],clc(e[i]));
            }
        }
        c[v]=2;
        f[v]+=w[v];
        return f[v];
    }
    
    struct dst{
        int p,h,l;
    }a[N],b[N];
    int in[S][2],cd[S][2],ocnt,st[S];
    vector<int>dt[S];
    
    bool cmp(dst a,dst b){
        return a.p<b.p||a.p==b.p&&a.h<b.h;
    }
    
    int bld(int l,int r,int bg,int ed){
        int mid=(l+r)>>1,v=++ocnt;
        in[v][0]=l;
        in[v][1]=r;
        cd[v][0]=cd[v][1]=0;
        int x,i,j,p;
        if(l<r){
            for(x=bg;x<=ed;x++)
                if(a[x].p>mid)break;
            cd[v][0]=bld(l,mid,bg,x-1);
            cd[v][1]=bld(mid+1,r,x,ed);
            for(p=bg,i=bg,j=x;i<x||j<=ed;p++)
                if(j>ed||i<x&&a[i].h<=a[j].h)
                    b[p]=a[i++];
                else
                    b[p]=a[j++];
            for(i=bg;i<=ed;i++)
                a[i]=b[i];
        }
        st[v]=cnt+1;
        vector<int>().swap(dt[v]);
        dt[v].resize(ed-bg+1);
        for(i=bg;i<=ed;i++){
            ++cnt;
            dt[v][i-bg]=a[i].h;
            pshe(cnt,t1[a[i].l]);
            if(i<ed)pshe(cnt,cnt+1);
        }
        return v;
    }
    
    int bnsr(int h,int v){
        int l=0,r=dt[v].size()-1,mid;
        while(l<=r){
            mid=(l+r)>>1;
            if(dt[v][mid]>=h)
                r=mid-1;
            else
                l=mid+1;
        }
        return l;
    }
    
    void addsgm(int d,int h,int v){
        int x=bnsr(h,v);
        if(x<dt[v].size())
            pshe(d,st[v]+x);
    }
    
    void lksgm(int d,int h,int v,int l,int r){
        if(l<=in[v][0]&&in[v][1]<=r){
            addsgm(d,h,v);
            return;
        }
        if(l<=in[cd[v][0]][1])
            lksgm(d,h,cd[v][0],l,r);
        if(in[cd[v][1]][0]<=r)
            lksgm(d,h,cd[v][1],l,r);
    }
    
    int gtmn(int l,int r){
        return min(gr[l][lg2[r-l]],gr[r-(1<<lg2[r-l])+1][lg2[r-l]]);
    }
    
    int n,na,nb;
    
    int bnsrl(int p,int h){
        int l=1,r=p,mid;
        while(l<=r){
            mid=(l+r)>>1;
            if(gtmn(mid,p)>=h)
                r=mid-1;
            else
                l=mid+1;
        }
        return l-1;
    }
    
    int bnsrr(int p,int h){
        int l=p+1,r=n,mid;
        while(l<=r){
            mid=(l+r)>>1;
            if(gtmn(p+1,mid)>=h)
                l=mid+1;
            else
                r=mid-1;
        }
        return r;
    }
    
    void cpt(){
        scanf("%s",s+1);
        n=strlen(s+1);
        gtsa(n,127);
        cnt=ocnt=ecnt=0;
        memset(l,0,sizeof(l));
        memset(w,0,sizeof(w));
        int i,la,ra,lb,rb,m,u,v;
        scanf("%d",&na);
        for(i=1;i<=na;i++){
            scanf("%d%d",&la,&ra);
            a[i].p=rk[la];
            a[i].h=ra-la+1;
            a[i].l=i;
            t1[i]=++cnt;
            w[t1[i]]=a[i].h;
        }
        sort(a+1,a+na+1,cmp);
        int rt=bld(1,n,1,na);
        scanf("%d",&nb);
        for(i=1;i<=nb;i++){
            scanf("%d%d",&lb,&rb);
            b[i].p=rk[lb];
            b[i].h=rb-lb+1;
            t2[i]=++cnt;
            la=bnsrl(b[i].p,b[i].h);
            ra=bnsrr(b[i].p,b[i].h);
            lksgm(t2[i],b[i].h,rt,la,ra);
        }
        scanf("%d",&m);
        for(i=1;i<=m;i++){
            scanf("%d%d",&u,&v);
            pshe(t1[u],t2[v]);
        }
        memset(c,0,sizeof(c));
        memset(f,0,sizeof(f));
        i64 ans=0;
        for(i=1;i<=na;i++){
            if(clc(t1[i])==-1){
                ans=-1;
                break;
            }
            ans=max(ans,clc(t1[i]));
        }
        printf("%lld
    ",ans);
    }
    
    int main()
    {
        int T,i;
        scanf("%d",&T);
        for(i=2;i<N;i++)
            lg2[i]=lg2[i>>1]+1;
        while(T--)
            cpt();
        return 0;
    }

    春节十二响(清明十二响):

    由一条链的部分分可以得到贪心做法,长链剖分即可。我用的斜堆。

    #include<iostream>
    #include<cstdio>
    #include<vector>
    using namespace std;
    typedef long long i64;
    const int N=2e5+5;
    
    int c[N][2],a[N],s[N];
    vector<int>e[N];
    
    int unn(int u,int v){
        if(!u)return v;
        if(!v)return u;
        if(a[u]<a[v])swap(u,v);
        c[u][1]=unn(c[u][1],v);
        s[u]+=s[v];
        if(s[c[u][1]]>s[c[u][0]])
            swap(c[u][0],c[u][1]);
        return u;
    }
    
    int mrg(int u,int v){
        if(!u)return v;
        if(!v)return u;
        int r=0,p,q;
        while(u&&v){
            p=u;
            u=unn(c[u][0],c[u][1]);
            c[p][0]=c[p][1]=0;
            s[p]=1;
            q=v;
            v=unn(c[v][0],c[v][1]);
            c[q][0]=c[q][1]=0;
            s[q]=1;
            if(a[p]<a[q])swap(p,q);
            r=unn(r,p);
        }
        if(u)r=unn(r,u);
        if(v)r=unn(r,v);
        return r;
    }
    
    int dfs(int v,int p){
        int r=0,i,u;
        for(i=0;i<e[v].size();i++)
            if(e[v][i]!=p)
                r=mrg(r,dfs(e[v][i],v));
        c[v][0]=c[v][1]=0;
        s[v]=1;
        r=unn(v,r);
    }
    
    i64 gtsz(int v){
        if(!v)return 0;
        return (i64)a[v]+gtsz(c[v][0])+gtsz(c[v][1]);
    }
    
    int main()
    {
        int n,i,f;
        scanf("%d",&n);
        for(i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(i=2;i<=n;i++){
            scanf("%d",&f);
            e[f].push_back(i);
        }
        printf("%lld",gtsz(dfs(1,0)));
        return 0;
    }
  • 相关阅读:
    杭州电acm理工大舞台版
    String.Split()功能
    android layout物业介绍
    讨厌OpenSSL
    Android Bundle类别
    多项式回归
    如何直接串行电缆以及空调制解调器串行电缆之间的区别?
    为什么写科技博客是情侣如此重要?
    SSH框架总结(帧分析+环境结构+示例源代码下载)
    RapidXml用法
  • 原文地址:https://www.cnblogs.com/wanghaoyu/p/Jointly-GivenEntranceExam2019.html
Copyright © 2011-2022 走看看