TJOI2018 Travel Notes

D1T1 - Mathematical Calculations

Just use the line segment tree/balanced tree to maintain the product of all numbers. I wrote a mathematical method with a rigid mind... It should be able to do \(\bmod\) multiplication and division of all numbers.
Time complexity \(O(nlogn)\) .

D1T2 - Quiz

Dichotomous answer + minimum intersectable path coverage. The topic is a bit confusing...

D1T3 - party

Icefox orz is a DDP that I don't know about. First list the DP equation of the longest common subsequence, \(dp[i][j]\) represents the first \(i\) bits of \(a_1\) and the first \(j\) of \(a_2\ ) LCS length of bits: \[ dp[i][j]=max(dp[i-1][j],dp[i][j-1],dp[i-1][j-1]+[ a_1[i]=a_2[j]]) \]It is observed that \(dp[i][j]\) is only 0/1 larger than \(dp[i][j-1]\) , so this The DP array is compressed into a binary number for DP. \(f[i][s]\) represents the number of schemes when the state of the DP array is \(s\) for a reward string of length \(i\) . It can be done by preprocessing the DP array to what state it will transition to according to the selection of the \(i\) bit. Since it is required that "NOI" cannot appear, it is good to add a one-dimensional record of the first two states. Time complexity \(O(n2^k)\) .

D2T1 - p

\(dp[i][j]\) indicates the number of strings that match the end of the string at the position \(j\) using the first \(i\) strings. Then for the \(i+1\)th kind of string, use KMP to get where it can match, and you can transfer to \(dp[i+1]\) . Time complexity \(O(|s|\Sigma a)\) .

D2T2 - free

It is basically a persistent trie tree bare question. But it seems that DFS will explode under Windows?
Time complexity \(O(n+30Q)\) .

D3T3 - Textbook profanity

It should be easy for those who have played Hearthstone to understand the questions. In addition, I often play the renegade Roaring Demon Blasphemy 233. The
ultimate goal is to seek \(S(n,k)=\sum_{i=1}^ni^k\) . There are two ways:
\[\begin{align*} (n+1)^{k+1}-n^{k+1} &= \binom{k+1}{1}n^k+\binom{ k+1}{2}n^{k-1}+...+\binom{k+1}{k+1}n^0 \\ n^{k+1}-(n-1)^ {k+1} &= \binom{k+1}{1}(n-1)^k+\binom{k+1}{2}(n-1)^{k-1}+...+ \binom{k+1}{k+1}(n-1)^0 \\ &... \\ 2^{k+1}-1^{k+1} &= \binom{k+1 }{1}1^k+\binom{k+1}{2}1^{k-1}+...+\binom{k+1}{k+1}1^0 \\ \end{align *}\] add, get
\[\begin{align*} (n+1)^{k+1}-1 &= \binom{k+1}{1}S(n,k)+\binom {k+1}{2}S(n,k-1)+...+\binom{k+1}{k+1}S(n,0) \\ S(n,k) &= \ frac{1}{k+1}((n+1)^{k+1}-\sum_{i=2}^{k+1}\binom{k+1}{i}S(n,k +1-i)-1) \end{align*}\] So we can find \(S(n,k)\) in \(O(k^2)\) time . Another way to do this is to use Bernoulli numbers .

First there is
\[ S(n,k)= \frac{1}{k+1} \sum_{i=1}^{k+1}\binom{k+1}{i}B_{k+1- i}(n+1)^i \] Where \(B\) is the Bernoulli number, the Bernoulli number satisfies \(B_0=1\) , for \(n>0\) there is
\[ \sum_{ i=0}^{n}\binom{n+1}{i}B_i=0 \] Then you can find it. Don't ask me why, I don't know!

Code

D1T1

#include <cstdio>
typedef long long lint;
inline char gc()
{
    static char now[1<<16],*s,*t;
    if(s==t) {t=(s=now)+fread(now,1,1<<16,stdin); if(s==t) return EOF;}
    return *s++;
}
inline int read()
{
    int x=0; char ch=gc();
    while(ch<'0'||'9'<ch) ch=gc();
    while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();
    return x;
}
const int N=1e4+10;
const int N1=1e5+10;
int cntP,pr[N1]; bool notP[N1];
int p1[N1],phi[N1];
void init()
{
    phi[1]=1;
    for(lint i=2;i<=1e5;i++)
    {
        if(!notP[i])
        {
            pr[++cntP]=i; p1[i]=i,phi[i]=i-1;
            for(lint j=i*i;j<=1e5;j*=i) p1[j]=j,phi[j]=(i-1)*(j/i);
        }
        for(int j=1;j<=cntP;j++)
        {
            if(i*pr[j]>1e5) break;
            int x=i*pr[j]; notP[x]=true;
            if(i%pr[j]) p1[x]=pr[j],phi[x]=phi[i]*(pr[j]-1);
            else {p1[x]=p1[i]*pr[j],phi[x]=phi[p1[x]]*phi[x/p1[x]]; break;}
        }
    }
}
int pow(int x,int y,int P)
{
    while(x<0) x+=P; 
    lint r=1,t=x;
    for(int i=y;i;i>>=1,t=t*t%P) if(i&1) r=r*t%P;
    return r;
}
int cnt,p[N],q[N]; lint m[N],a[N],k[N];
int getX()
{
    int a1=0,m1=1,phi1=1;
    for(int i=1;i<=cnt;i++)
    {
        int m2=m[i],a2=(k[i]>=q[i])?0:(a[i]*pow(p[i],k[i],m[i]));
        int phi2=(p[i]-1)*(m[i]/p[i]);
        lint t=1LL*a1*m2-1LL*a2*m1;
        while(t<0) t+=m1*m2;
        a1=t*pow(m2-m1,phi1*phi2-1,m1*m2)%(m1*m2);
        m1=m1*m2; phi1=phi1*phi2;
    }
    return a1;
}
int pos[N1];
void work0(int Q,int P)
{
    int ans=1;
    for(int owo=1;owo<=Q;owo++)
    {
        int opt=read(),x=read();
        pos[owo]=x;
        if(opt==1) ans=(lint)ans*x%P;
        else ans=(lint)ans*pow(pos[x],P-2,P)%P;
        printf("%d\n",ans);
    }
}
int main()
{
    freopen("cal.in","r",stdin);
    freopen("cal.out","w",stdout);
    int task=read(); init();
    while(task--)
    {
        
    int Q=read(),mod=read();
    cnt=0;
    for(int i=1,t=mod;i<=cntP+1;i++)
    {
        if(i==cntP+1&&t>1)
        {
            cnt++,p[cnt]=t,q[cnt]=1,m[cnt]=t,a[cnt]=1,k[cnt]=0;
            break;
        }
        if(t<pr[i]) break;
        if(t%pr[i]==0) cnt++,p[cnt]=pr[i],q[cnt]=0,m[cnt]=1,a[cnt]=1,k[cnt]=0;
        while(t%pr[i]==0) t/=pr[i],q[cnt]++,m[cnt]*=pr[i];
    }
    if(cnt<=1) {work0(Q,mod); continue;}
    for(int owo=1;owo<=Q;owo++)
    {
        int opt=read(),x=read();
        pos[owo]=x;
        if(opt==1)
        {
            for(int i=1;i<=cnt;i++)
            {
                int t=x;
                while(t%p[i]==0) t/=p[i],k[i]++;
                a[i]=(lint)a[i]*t%m[i];
            }
        }
        else
        {
            for(int i=1;i<=cnt;i++)
            {
                int t=pos[x];
                while(t%p[i]==0) t/=p[i],k[i]--;
                a[i]=(lint)a[i]*pow(t,(p[i]-1)*(m[i]/p[i])-1,m[i])%m[i];
            }
        }
        //for(int i=1;i<=cnt;i++) printf("=%d (mod %d) k=%d\n",a[i],m[i],k[i]);
        printf("%d\n",getX());
    }
    
    }
    return 0;
}

D1T2

//智力竞赛
#include <algorithm>
#include <cstdio>
#include <cstring>
using std::sort;
inline char gc()
{
    static char now[1<<16],*s,*t;
    if(s==t) {t=(s=now)+fread(now,1,1<<16,stdin); if(s==t) return EOF;}
    return *s++;
}
inline int read()
{
    int x=0; char ch=gc();
    while(ch<'0'||'9'<ch) ch=gc();
    while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();
    return x;
}
const int N=600;
int n,m,w[N]; bool ed[N][N],e[N][N];
int map[N];
struct rec{int w,id;} r[N];
bool cmpW(rec x,rec y) {return x.w<y.w;}
int n1; int link[N]; bool used[N];
bool find(int u)
{
    for(int v=1;v<=n1;v++)
    {
        if(!e[u][v]||used[v]) continue;
        used[v]=true;
        if(!link[v]||find(link[v])) {link[v]=u; return true;}
    }
    return false;
}
int match()
{
    int res=0; memset(link,0,sizeof link);
    for(int u=1;u<=n1;u++)
    {
        memset(used,0,sizeof used);
        if(find(u)) res++;
    }
    return res;
}
bool check(int x)
{
    n1=x;
    memset(e,false,sizeof e);
    for(int u=1;u<=n1;u++)
        for(int v=1;v<=n1;v++)
            e[u][v]=ed[u][v];
    for(int k=1;k<=n1;k++)
        for(int u=1;u<=n1;u++)
            for(int v=1;v<=n1;v++)
                e[u][v]|=e[u][k]&&e[k][v];
    return n1-match()<=m;
}
int main()
{
    freopen("contest.in","r",stdin);
    freopen("contest.out","w",stdout);
    m=read()+1,n=read();
    for(int i=1;i<=n;i++)
    {
        r[i].w=read(),r[i].id=i; int x=read();
        for(int j=1;j<=x;j++) e[i][read()]=true;
    }
    sort(r+1,r+n+1,cmpW);
    for(int i=1;i<=n;i++) w[i]=r[i].w,map[r[i].id]=i;
    for(int u=1;u<=n;u++)
        for(int v=1;v<=n;v++) if(e[u][v]) ed[map[u]][map[v]]=true;
    int L=1,R=n;
    while(L<=R)
    {
        int mid=L+R>>1;
        if(check(mid)) L=mid+1;
        else R=mid-1;
    }
    if(R<n) printf("%d\n",r[R+1].w);
    else puts("AK");
    return 0;
}

D1T3

//party
#include <cstdio>
#include <cstring>
inline int max(int x,int y) {return x>y?x:y;}
const int S=1<<16;
const int P=1e9+7;
int n,m,U; char s0[20];
int tr1[S][3],tr2[3][3];
int f1[20],f2[20];
int getDP(int x)
{
    for(int i=1;i<=m;i++)
        f2[i]=max(f1[i-1]+(x==s0[i]),max(f1[i],f2[i-1]));
    int s=0;
    for(int i=1;i<=m;i++) s|=(f2[i]-f2[i-1])<<i-1;
    return s;
}
int dp[2][S][4];
int bitcnt(int s) {int r=0; while(s) r+=s&1,s>>=1; return r;}
int ans[20];
int main()
{
    freopen("party.in","r",stdin);
    freopen("party.out","w",stdout);
    scanf("%d%d",&n,&m); scanf("%s",s0+1);
    for(int i=1;i<=m;i++)
        if(s0[i]=='N') s0[i]=0;
        else if(s0[i]=='O') s0[i]=1;
        else s0[i]=2;
    U=(1<<m)-1;
    for(int s=0;s<=U;s++)
    {
        for(int i=1;i<=m;i++) f1[i]=f1[i-1]+((s>>i-1)&1);
        for(int k=0;k<3;k++) tr1[s][k]=getDP(k);
    }
    tr2[0][0]=1;
    tr2[1][0]=1,tr2[1][1]=2;
    tr2[2][0]=1,tr2[2][2]=3;
    int c=0; dp[c][0][0]=1;
    for(int i=1;i<=n;i++)
    {
        c^=1;
        for(int s1=0;s1<=U;s1++)
            for(int s2=0;s2<3;s2++)
                for(int k=0;k<3;k++)
                    dp[c][tr1[s1][k]][tr2[s2][k]]+=dp[c^1][s1][s2],dp[c][tr1[s1][k]][tr2[s2][k]]%=P;
        memset(dp[c^1],0,sizeof dp[c^1]);
    }
    for(int s=0;s<=U;s++) ans[bitcnt(s)]=((long long)ans[bitcnt(s)]+dp[c][s][0]+dp[c][s][1]+dp[c][s][2])%P;
    for(int i=0;i<=m;i++) printf("%d\n",ans[i]);
    return 0;
}

D2T1

//str
#include <cstdio>
#include <cstring>
const int N=1e4+10;
const int P=1e9+7;
int n,k; char s[N],s0[30];
int f[2][N];
int nxt[30];
void getNxt(char s[])
{
    int len=strlen(s+1);
    nxt[0]=nxt[1]=0;
    for(int i=2;i<=len;i++)
    {
        int j=nxt[i-1];
        while(j&&s[i]!=s[j+1]) j=nxt[j];
        if(s[i]==s[j+1]) nxt[i]=j+1;
        else nxt[i]=0;
    }
}
int main()
{
    freopen("str.in","r",stdin);
    freopen("str.out","w",stdout);
    scanf("%d",&k);
    scanf("%s",s+1),n=strlen(s+1);
    int c=0;
    for(int i=0;i<=n;i++) f[c][i]=1;
    for(int owo=0;owo<k;owo++,c^=1)
    {
        memset(f[c^1],0,sizeof f[c^1]);
        int cnt; scanf("%d",&cnt);
        while(cnt--)
        {
            scanf("%s",s0+1); getNxt(s0);
            int len=strlen(s0+1);
            for(int i=1,j=0;i<=n;i++)
            {
                while(j&&s[i]!=s0[j+1]) j=nxt[j];
                if(s[i]==s0[j+1]) j++;
                if(j==len) f[c^1][i]=(f[c^1][i]+f[c][i-len])%P;
            }
        }
    }
    int ans=0;
    for(int i=0;i<=n;i++) ans=(ans+f[c][i])%P;
    printf("%d\n",ans);
    return 0;
}

D2T2

//xor
#include <algorithm>
#include <cstdio>
using namespace std;
inline char gc()
{
    static char now[1<<16],*s,*t;
    if(s==t) {t=(s=now)+fread(now,1,1<<16,stdin); if(s==t) return EOF;}
    return *s++;
}
inline int read()
{
    int x=0; char ch=gc();
    while(ch<'0'||'9'<ch) ch=gc();
    while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();
    return x;
}
const int N=1e5+10;
int n,w[N];
int edCnt,h[N];
struct edge{int v,nxt;} ed[N<<1];
void edAdd(int u,int v)
{
    edCnt++; ed[edCnt].v=v,ed[edCnt].nxt=h[u],h[u]=edCnt;
    edCnt++; ed[edCnt].v=u,ed[edCnt].nxt=h[v],h[v]=edCnt;
}
int fa[N][20],dpt[N];
int dfCnt,dfn[N],fr[N],to[N];
void dfs(int u)
{
    dfn[++dfCnt]=u; fr[u]=dfCnt;
    for(int k=1;k<=17;k++) fa[u][k]=fa[fa[u][k-1]][k-1];
    for(int i=h[u];i;i=ed[i].nxt)
    {
        int v=ed[i].v;
        if(v==fa[u][0]) continue;
        fa[v][0]=u,dpt[v]=dpt[u]+1,dfs(v);
    }
    to[u]=dfCnt;
}
inline lca(int u,int v)
{
    if(dpt[u]<dpt[v]) swap(u,v);
    for(int k=17;k>=0;k--) if(dpt[fa[u][k]]>=dpt[v]) u=fa[u][k];
    if(u==v) return u;
    for(int k=17;k>=0;k--) if(fa[u][k]!=fa[v][k]) u=fa[u][k],v=fa[v][k];
    return fa[u][0];
}
const int N1=N*31;
int rt1[N],rt2[N];
int ndCnt,ch[N1][2],siz[N1];
inline void ndCopy(int p,int &q) {ch[p][0]=ch[q][0],ch[p][1]=ch[q][1],siz[p]=siz[q];}
void ins(int &p,int x,int d)
{
    ndCopy(++ndCnt,p);
    p=ndCnt; siz[p]++; 
    if(d<0) return;
    int t=(x>>d)&1;
    ins(ch[p][t],x,d-1);
}
void bldTr2(int u)
{
    ins(rt2[u]=rt2[fa[u][0]],w[u],30);
    for(int i=h[u];i;i=ed[i].nxt)
    {
        int v=ed[i].v;
        if(v!=fa[u][0]) bldTr2(v);
    }
}
int qres;
void query1(int p1,int p2,int x)
{
    int now=0;
    for(int d=30;d>=0;d--)
    {
        int t=((x>>d)&1)^1,sizT=siz[ch[p2][t]]-siz[ch[p1][t]];
        if(!sizT) t^=1;
        p1=ch[p1][t],p2=ch[p2][t],now|=t<<d;
    }
    qres=x^now;
}
void query2(int p1,int p2,int p3,int x)
{
    int now=0;
    for(int d=30;d>=0;d--)
    {
        int t=((x>>d)&1)^1,sizT=siz[ch[p1][t]]+siz[ch[p2][t]]-siz[ch[p3][t]]*2;
        if(!sizT) t^=1;
        p1=ch[p1][t],p2=ch[p2][t],p3=ch[p3][t],now|=t<<d;
    }
    qres=x^now;
}

void show(int p)
{
    if(!p) return;
    printf("%2d siz=%d ch=%d,%d\n",p,siz[p],ch[p][0],ch[p][1]);
    show(ch[p][0]); show(ch[p][1]);
}

int main()
{
    freopen("xor.in","r",stdin);
    freopen("xor.out","w",stdout);
    n=read(); int Q=read();
    for(int i=1;i<=n;i++) w[i]=read();
    for(int i=1;i<=n-1;i++)
    {
        int u=read(),v=read();
        edAdd(u,v);
    }
    fa[1][0]=0,dpt[1]=1,dfs(1);
    for(int i=1;i<=n;i++) ins(rt1[i]=rt1[i-1],w[dfn[i]],30);
    bldTr2(1);
    /*for(int i=1;i<=n;i++) show(rt1[i]),puts("");
    puts("");
    for(int i=1;i<=n;i++) show(rt2[i]),puts("");*/

    while(Q--)
    {
        int opt=read();
        if(opt==1)
        {
            int u=read(),x=read();
            qres=0; query1(rt1[fr[u]-1],rt1[to[u]],x);
        }
        else
        {
            int u=read(),v=read(),x=read();
            int t=lca(u,v);
            qres=0; query2(rt2[u],rt2[v],rt2[t],x);
            qres=max(qres,w[t]^x);
        }
        printf("%d\n",qres);
    }
    return 0;
}

D2T3

//教科书般的亵渎
#include <algorithm>
#include <cstdio>
using std::sort;
typedef long long lint;
inline lint read()
{
    lint x=0; char ch=getchar();
    while(ch<'0'||'9'<ch) ch=getchar();
    while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x;
}
const int P=1e9+7;
const int M=60;
lint n,a[M]; int m;
int B[M],C[M][M],inv[M];
void init(int n)
{
    inv[1]=1;
    for(int i=2;i<=n;i++) inv[i]=1LL*inv[P%i]*(P-P/i)%P;
    for(int i=0;i<=n;i++)
    {
        C[i][0]=1;
        for(int j=1;j<=i;j++) C[i][j]=(C[i-1][j-1]+C[i-1][j])%P;
    }
    B[0]=1;
    for(int i=1;i<=n-1;i++)
    {
        B[i]=0;
        for(int j=0;j<=i-1;j++) B[i]=(B[i]+1LL*C[i+1][j]*B[j])%P;
        B[i]=(1LL*(P-B[i])*inv[i+1])%P;
    }
}
int pow(lint x,int y)
{
    lint r=1,t=x;
    for(int i=y;i;i>>=1,t=t*t%P) if(i&1) r=r*t%P;
    return r;
}
int S(lint n)
{
    int s=0;
    for(int i=1;i<=m+1;i++) s=(s+1LL*C[m+1][i]*B[m+1-i]%P*pow(n+1,i)%P)%P;
    s=1LL*s*inv[m+1]%P;
    //printf("Sigma(%d,%d)=%d\n",n,m,s);
    return s;
}
int main()
{
    freopen("defile.in","r",stdin);
    freopen("defile.out","w",stdout);
    init(59);
    int task=read();
    while(task--)
    {

    n=read(),m=read();
    for(int i=1;i<=m;i++) a[i]=read();
    a[++m]=++n; sort(a+1,a+m+1);
    lint ans=0;
    for(int i=1;i<=m;i++)
    {
        for(int j=i;j<=m;j++) ans=(ans+S(a[j]-1)-S(a[j-1])+P)%P;
        for(int j=i+1;j<=m;j++) a[j]-=a[i]; a[i]=0;
    }
    printf("%lld\n",ans);

    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325261668&siteId=291194637