SDOI2017 R2 Day2

Posted sovietpower

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SDOI2017 R2 Day2相关的知识,希望对你有一定的参考价值。

2018.4.29 Test

时间:7:30~11:30(实际没用多少)
实际得分:0+20+30=50

总结

LOJ总题目链接

T1 BZOJ.4912.[SDOI2017]天才黑客

题目链接

T2 BZOJ.4913.[SDOI2017]遗忘的集合

题目链接

正解生成函数什么的
部分分有点坑
弃了

T3 BZOJ.4914.[SDOI2017]文本校正

题目链接

考试代码

T1

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
const int N=5e4+5,S=2e4+5;

int n,m,k,l1,l2,Enum,H[N],to[N],nxt[N],len[N],pos[N],Ans[N];
char s1[S],s2[S];
struct Trie
{
    int c[S],dep[N],to[S],nxt[S],H[S],Enum,top[S],fa[S],son[S],sz[S],id,pos[S];

    inline void Add(int u,int v,int w){
        to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum, c[Enum]=w;
    }
    void Init(){
        Enum=0, memset(H,0,sizeof H), id=0;
    }
    void DFS1(int x)
    {
        int mx=0; sz[x]=1, son[x]=0;
        for(int v,i=H[x]; i; i=nxt[i])
            if((v=to[i])!=fa[x])
            {
                fa[v]=x, dep[v]=dep[x]+1, DFS1(v), sz[x]+=sz[v];
                if(mx<sz[v]) mx=sz[v], son[x]=v;
            }
    }
    void DFS2(int x,int tp)
    {
        top[x]=tp, pos[x]=++id;
        if(son[x]){
            DFS2(son[x],tp);
            for(int i=H[x]; i; i=nxt[i])
                if(to[i]!=fa[x]&&to[i]!=son[x]) DFS2(to[i],to[i]);
        }
    }
    int Query(int u,int v)
    {
        if(u==1||v==1) return 0;
        while(top[u]!=top[v])
        {
            if(dep[top[u]]<dep[top[v]]) std::swap(u,v);
            u=fa[top[u]];
        }
        return dep[u]<dep[v]?dep[u]:dep[v];
    }
}t;

inline int read()
{
    int now=0;register char c=gc();
    for(;!isdigit(c);c=gc());
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now;
}
inline void AddEdge(int u,int v,int w,int p){
    to[++Enum]=v, len[Enum]=w, nxt[Enum]=H[u], pos[v]=p, H[u]=Enum;
}


int main()
{
    freopen("hack.in","r",stdin);
//  freopen("hack.out","w",stdout);

    int T=read();
    while(T--)
    {
        memset(Ans,0x7f,sizeof Ans);
        memset(H,0,sizeof H);
        Enum=0;
        n=read(),m=read(),k=read();
        for(int u,v,w,i=1; i<=m; ++i)
            u=read(),v=read(),w=read(),AddEdge(u,v,w,read());
        for(int u,v,i=1; i<k; ++i)
            u=read(),v=read(),t.Add(v,u,read());
        for(int x=1; x<=n; ++x)
            for(int i=H[x]; i; i=nxt[i])
                len[i]+=t.Query(pos[x],pos[to[i]]);

    }
    fclose(stdin);fclose(stdout);
    return 0;
}

T2

#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
const int N=(1<<18)+5;//262149

int n,p,f[N],g[N],cnt,s[N];
long long ans;

inline int read()
{
    int now=0;register char c=gc();
    for(;!isdigit(c);c=gc());
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now;
}
void DFS(int sta,int pur,int sum)
{
    if(sum==pur) ++ans;
    else{
        for(int i=sta; i<=cnt; ++i)
            if(sum+s[i]<=pur) DFS(i,pur,sum+s[i]);
            else break;
    }
}
void Spec()
{
    srand(20180430);
    for(int i=1; i<=n; ++i) s[i]=i;
    bool flag=0;
    for(int i=1; i<=25; ++i)
    {
        s[++cnt]=i, ans=0, DFS(1,i,0), ans%=p;
        if(ans>f[i]) {flag=1; break;}
    }
    if(!flag) cnt+=rand()%(n-cnt)+1;
    --cnt;
    printf("%d\n",cnt);
    for(int i=1; i<=cnt; ++i) printf("%d ",s[i]);
}

int main()
{
    freopen("set.in","r",stdin);
    freopen("set.out","w",stdout);

    n=read(),p=read();
    for(int i=1; i<=n; ++i) f[i]=read();
    if(n>5000) {Spec(); return 0;}
    if(f[1]) s[++cnt]=1;
    if(f[2]>1||(f[2]&&!f[1])) s[++cnt]=2;
//  g[0]=1, g[1]=f[1], g[2]=f[2];
    for(int i=3; i<=n; ++i)
    {
//      for(int j=1; j<=cnt/*&&s[j]<=i*/; ++j)
//          (g[i]+=g[i-s[j]])%=p;
//      ++g[i], g[i]>>=1;
        ans=0, DFS(1,i,0), ans%=p;//O(2^cnt)
//      printf("%d:%lld\n",i,ans);
        if(ans!=f[i]) s[++cnt]=i;
    }
    printf("%d\n",cnt);
    for(int i=1; i<=cnt; ++i) printf("%d ",s[i]);


    fclose(stdin);fclose(stdout);
    return 0;
}

T3

#include <cstdio>
#include <cctype>
#define gc() getchar()
typedef unsigned long long ull;
const int N=1e6+5;
const ull seed=200009;

int n,m,S[N],T[N];
ull pw[N],hs_S[N],hs_T[N];

inline int read()
{
    int now=0;register char c=gc();
    for(;!isdigit(c);c=gc());
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now;
}
void Init(int n){
    pw[0]=1;
    for(int i=1; i<=n; ++i) pw[i]=pw[i-1]*seed;
}
inline ull Get_Hash(int l,int r,ull *hs){
    return hs[r]-hs[l-1]*pw[r-l+1];
}

int main()
{
//  freopen("fix.in","r",stdin);
//  freopen("fix.out","w",stdout);

    Init(1000000);
    int Case=read(),pos1,pos2,l1,l2,l3;
    ull hs1,hs2,hs3;
    while(Case--)
    {
        n=read(),m=read();
//      if(n>5000) break;
        for(int i=1; i<=n; ++i) S[i]=read();
        for(int i=1; i<=n; ++i) T[i]=read();
        for(int i=1; i<=n; ++i)
            hs_S[i]=hs_S[i-1]*seed+S[i],hs_T[i]=hs_T[i-1]*seed+T[i];
        int f=0;
        for(int i=1; i<n&&!f; ++i)
            for(int j=i+1; j<n; ++j)
            {
                l1=i, l2=j-i, l3=n-j;
                hs1=Get_Hash(1,i,hs_T), hs2=Get_Hash(i+1,j,hs_T), hs3=Get_Hash(j+1,n,hs_T);
//              printf("%d %d %lld %lld %lld\n",i,j,hs1,hs2,hs3);
                if((hs1==Get_Hash(1,i,hs_S)&&hs2==Get_Hash(i+1,j,hs_S)&&hs3==Get_Hash(j+1,n,hs_S))) f=1;
                else if((hs1==Get_Hash(1,i,hs_S)&&hs3==Get_Hash(i+1,i+l3,hs_S)&&hs2==Get_Hash(i+l3+1,n,hs_S))) f=2;
                else if((hs2==Get_Hash(1,l2,hs_S)&&hs1==Get_Hash(l2+1,l2+l1,hs_S)&&hs3==Get_Hash(l2+l1+1,n,hs_S))) f=3;
                else if((hs2==Get_Hash(1,l2,hs_S)&&hs3==Get_Hash(l2+1,l2+l3,hs_S)&&hs1==Get_Hash(l2+l3+1,n,hs_S))) f=4;
                else if((hs3==Get_Hash(1,l3,hs_S)&&hs1==Get_Hash(l3+1,l3+l1,hs_S)&&hs2==Get_Hash(l3+l1+1,n,hs_S))) f=5;
                else if((hs3==Get_Hash(1,l3,hs_S)&&hs2==Get_Hash(l3+1,l3+l2,hs_S)&&hs1==Get_Hash(l3+l2+1,n,hs_S))) f=6;  
                if(f) {pos1=i, pos2=j; break;}
            }//按拼接顺序。。
        switch(f)
        {
            case 0: puts("NO"); break;
            case 1: printf("YES\n%d %d\n%d %d\n%d %d\n",1,pos1,pos1+1,pos2,pos2+1,n); break;
            case 2: printf("YES\n%d %d\n%d %d\n%d %d\n",1,pos1,pos2+1,n,pos1+1,pos2); break;
            case 3: printf("YES\n%d %d\n%d %d\n%d %d\n",pos1+1,pos2,1,pos1,pos2+1,n); break;
            case 4: printf("YES\n%d %d\n%d %d\n%d %d\n",pos1+1,pos2,pos2+1,n,1,pos1); break;
            case 5: printf("YES\n%d %d\n%d %d\n%d %d\n",pos2+1,n,1,pos1,pos1+1,pos2); break;
            case 6: printf("YES\n%d %d\n%d %d\n%d %d\n",pos2+1,n,pos1+1,pos2,1,pos1); break;
        }
    }
//  fclose(stdin);fclose(stdout);
    return 0;
}

以上是关于SDOI2017 R2 Day2的主要内容,如果未能解决你的问题,请参考以下文章

SDOI2013 R1 Day2

COGS 723. [SDOI2007] 超级数组

数论 Day2基础归纳法 题解

codevs 5964 [SDOI2017]序列计数

P3704 [SDOI2017]数字表格

P3702 [SDOI2017]序列计数