• 好多考试....


    11.01 早上考试

    T1 虎...

    这题真是虎,大力才结论,水掉了...

    每一次翻转一定是只翻转白色连续的一段,然后dfs一遍就行了

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <iostream>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rint register int
    using namespace std;
    inline void read(int &x)
    {
        x=0; int ff=1; char q=getchar();
        while(q<'0'||q>'9') { if(q=='-') ff=-1; q=getchar(); }
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
        x*=ff;
    }
    const int N=1000006;
    int first[N],nt[N<<1],ver[N<<1],clo[N<<1],fina[N<<1],e;
    void addbian(int u,int v,int _clo,int _fina)
    {
        ver[e]=v; clo[e]=_clo;
        fina[e]=_fina;
        nt[e]=first[u];
        first[u]=e++;
    }
    
    int n;
    int ans;
    
    int fa[N],g[N];
    void dfs(int x)
    {
        g[x]=0;
        int i,sum=0;
        for(i=first[x];i!=-1;i=nt[i])
            if(ver[i]!=fa[x])
            {
                fa[ver[i]]=x;
                dfs(ver[i]);
                if(!fina[i])
                {
                    if(g[ver[i]])
                        ++sum;
                }
                else
                {
                    if(!g[ver[i]])
                    {
                        if(!clo[i]) ++sum;
                    }
                    else
                    {
                        if(clo[i]) ++ans;
                        else ++sum;
                    }
                }
            }
        ans+=(sum>>1);
        if(sum&1) g[x]=1;
        else g[x]=0;
        if(x==1&&g[x])
            ++ans;
    }
    
    int main(){
        
        //freopen("T1.in","r",stdin);
        
        //freopen("tiger.in","r",stdin);
        //freopen("tiger.out","w",stdout);
        
        rint i; int tin1,tin2,tin3;
        mem(first,-1);
        
        read(n);
        
        for(i=2;i<=n;++i)
        {
            read(tin1); read(tin2); read(tin3);
            if(tin2!=0) tin2=1;
            if(tin3!=0) tin3=1;
            addbian(i,tin1,tin2,tin3);
            addbian(tin1,i,tin2,tin3);
        }
        dfs(1);
        cout<<ans;
    }
    T1

    T2  阴阳

    30分暴搜

    打表再来30分

    正解是dp

    发现黑白一定是分成两块,并且边界是单调的

    分黑白在两边和边界单调下降什么的搞就行了

    最后去掉重

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rint register int
    using namespace std;
    inline void read(int &x)
    {
        x=0; char q=getchar();
        while(q<'0'||q>'9') q=getchar();
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
    }
    inline void readchar(char &x)
    {
        x=getchar();
        while(x!='B'&&x!='W'&&x!='?') x=getchar();
    }
    const int mod=1e9+7;
    
    int n,m;
    char v[1006][1006];
    ll f[1006][1006];
    int wbl[1006],wbr[1006],bwl[1006],bwr[1006];
    int t1[1006],t2[1006],t3[1006],t4[1006];
    
    ll dp()
    {
        rint i,j,k; int l,r,tt; ll sum,an=0;
        
        for(i=1;i<=n;++i)
        {
            r=0; l=m;
            while(r<=m&&v[i][r]!='W') ++r; --r;
            while(l>=0&&v[i][l]!='B') --l;
            if(l<0) ++l;
            bwl[i]=l; bwr[i]=r;
            r=0; l=m;
            while(r<=m&&v[i][r]!='B') ++r; --r;
            while(l>=0&&v[i][l]!='W') --l;
            if(l<0) ++l;
            wbl[i]=l; wbr[i]=r;
        }
        
        // bl|wh
        mem(f,0);
        l=bwl[1]; r=bwr[1];
        //printf("l=%d r=%d
    ",l,r);
        for(j=l;j<=r;++j) f[1][j]=1;
        for(i=2;i<=n;++i)
        {
            l=bwl[i]; r=bwr[i];
            //printf("l=%d r=%d
    ",l,r);
            sum=0;
            for(k=r+1;k<=m;++k)
                sum=(sum+f[i-1][k])%mod;
            for(j=r;j>=l;--j)
            {
                sum=(sum+f[i-1][j])%mod;
                f[i][j]=sum;
            }
        }
        //printf("pr1an=%lld
    ",an);
        for(j=0;j<=m;++j)
            an=(an+f[n][j])%mod;
        //printf("ho1an=%lld
    ",an);
        // blwh
        mem(f,0);
        l=bwl[1]; r=bwr[1];
        for(j=l;j<=r;++j) f[1][j]=1;
        for(i=2;i<=n;++i)
        {
            l=bwl[i]; r=bwr[i];
            sum=0;
            for(k=0;k<l;++k)
                sum=(sum+f[i-1][k])%mod;
            for(j=l;j<=r;++j)
            {
                sum=(sum+f[i-1][j])%mod;
                f[i][j]=sum;
            }
        }
        for(j=0;j<=m;++j)
            an=(an+f[n][j])%mod;
        // wh/bl
        mem(f,0);
        l=wbl[1]; r=wbr[1];
        for(j=l;j<=r;++j) f[1][j]=1;
        for(i=2;i<=n;++i)
        {
            l=wbl[i]; r=wbr[i];
            sum=0;
            for(k=r+1;k<=m;++k)
                sum=(sum+f[i-1][k])%mod;
            for(j=r;j>=l;--j)
            {
                sum=(sum+f[i-1][j])%mod;
                f[i][j]=sum;
            }
        }
        for(j=0;j<=m;++j)
            an=(an+f[n][j])%mod;
        // whl
        mem(f,0);
        l=wbl[1]; r=wbr[1];
        for(j=l;j<=r;++j) f[1][j]=1;
        for(i=2;i<=n;++i)
        {
            l=wbl[i]; r=wbr[i];
            sum=0;
            for(k=0;k<l;++k)
                sum=(sum+f[i-1][k])%mod;
            for(j=l;j<=r;++j)
            {
                sum=(sum+f[i-1][j])%mod;
                f[i][j]=sum;
            }
        }
        for(j=0;j<=m;++j)
            an=(an+f[n][j])%mod;
        
        // whl
        // wh/bl
        // blwh
        // bl/wh
        
        //int wbmnl1=0,wbmxr1=m,bwmnl1=0,bwmxr1=m;
        //int wbmnl2=0,wbmxr2=n,bwmnl2=0,bwmxr2=n;
        int l0,r0;
        int whnum=0,blnum=0;
        
        l=0; r=m;
        for(i=1;i<=n;++i)
        {
            if(l<wbl[i]) l=wbl[i];
            if(r>wbr[i]) r=wbr[i];
        }
        //printf("l=%d r=%d
    ",l,r);
        for(i=l;i<=r;++i)
            t1[i]+=2;
        if(l==0) blnum+=1;
        if(r==m) whnum+=1;
        
        l=0; r=m;
        for(i=1;i<=n;++i)
        {
            if(l<bwl[i]) l=bwl[i];
            if(r>bwr[i]) r=bwr[i];
        }
        //printf("l=%d r=%d
    ",l,r);
        for(i=l;i<=r;++i)
            t2[i]+=2;
        if(l==0) whnum+=1;
        if(r==m) blnum+=1;
        
        l0=0; r0=n;
        for(j=1;j<=m;++j)
        {
            l=n; r=0;
            while(l>=0&&v[l][j]!='B') --l;
            if(l<0) ++l;
            while(r<=n&&v[r][j]!='W') ++r; --r;
            if(l0<l) l0=l;
            if(r0>r) r0=r;
        }
        //printf("l0=%d r0=%d
    ",l0,r0);
        for(i=l0;i<=r0;++i)
            t3[i]+=2;
        if(l0==0) whnum+=1;
        if(r0==n) blnum+=1;
        
        l0=0; r0=n;
        for(j=1;j<=m;++j)
        {
            l=n; r=0;
            while(l>=0&&v[l][j]!='W') --l;
            if(l<0) ++l;
            while(r<=n&&v[r][j]!='B') ++r; --r;
            if(l0<l) l0=l;
            if(r0>r) r0=r;
        }
        //printf("l0=%d r0=%d
    ",l0,r0);
        for(i=l0;i<=r0;++i)
            t4[i]+=2;
        if(l0==0) blnum+=1;
        if(r0==n) whnum+=1;
        
        //printf("prpran=%lld
    ",an);
        
        if(blnum) an=(an-blnum+1+mod)%mod;
        if(whnum) an=(an-whnum+1+mod)%mod;
        
        //printf("pran=%lld
    ",an);
        
        for(i=1;i<m;++i)
        {
            if(t1[i]) an=(an-t1[i]+1+mod)%mod;
            if(t2[i]) an=(an-t2[i]+1+mod)%mod;
        }
        for(i=1;i<n;++i)
        {
            if(t3[i]) an=(an-t3[i]+1+mod)%mod;
            if(t4[i]) an=(an-t4[i]+1+mod)%mod;
        }
        
        //printf("an=%lld
    ",an);
        return (an%mod+mod)%mod;
    }
    
    int main(){
        
        //freopen("T2.in","r",stdin);
        //freopen("T2.out","w",stdout);
        
        rint i,j;
        
        read(n); read(m);
        for(i=1;i<=n;++i)
            for(j=1;j<=m;++j)
                readchar(v[i][j]);
        printf("%lld",dp());
    }
    T2

    T3 山洞

    真正题意:

    走m次,第i次走i步,又正好在第m次走回来的方案数

    注意两个方案不同当且仅当走过的山洞排列有一个不同

    直接矩阵乘,循环矩阵$O(n^2logm)$

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rint register int
    using namespace std;
    inline void read(int &x)
    {
        x=0; char q=getchar();
        while(q<'0'||q>'9') q=getchar();
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
    }
    const int mod=1e9+7;
    
    int n,m;
    ll f[1006],a1[1006][1006],a[1006][1006],t[1006];
    
    ll dp()
    {
        rint i,j,k,p; int t1,t2,ci;
        for(i=0;i<n;++i) a[i][i]=1;
        for(p=1;p<=n;++p)
        {
            for(i=0;i<n;++i)
            {
                t[i]=0;
                t1=(i-p+n)%n;
                t[i]=(t[i]+a[0][t1])%mod;
                t2=(i+p)%n;
                if(t1!=t2)
                    t[i]=(t[i]+a[0][t2])%mod;
            }
            for(i=0;i<n;++i)
                a[0][i]=t[i];
            /*for(i=0;i<n;++i)
                printf("%lld ",a[0][i]);
            printf("
    ");*/
        }
        for(i=1;i<n;++i)
        {
            a[i][0]=a[i-1][n-1];
            for(j=1;j<n;++j)
                a[i][j]=a[i-1][j-1];
        }
        
        /*printf("
    ");
        for(i=0;i<n;++i)
        {
            for(j=0;j<n;++j)
                printf("%lld ",a[i][j]);
            printf("
    ");
        }
        printf("
    ");*/
        
        ci=m/n; m=m-n*ci;
        //printf("ci=%d
    ",ci);
        f[0]=1;
        while(ci)
        {
            if(ci&1)
            {
                for(i=0;i<n;++i)
                {
                    t[i]=0;
                    for(k=0;k<n;++k)
                        t[i]=(t[i]+f[k]*a[k][i]%mod)%mod;
                }
                for(i=0;i<n;++i)
                    f[i]=t[i];
            }
            for(i=0;i<n;++i)
            {
                t[i]=0;
                for(k=0;k<n;++k)
                    t[i]=(t[i]+a[0][k]*a[k][i]%mod)%mod;
            }
            for(i=0;i<n;++i)
                a[0][i]=t[i];
            for(i=1;i<n;++i)
            {
                a[i][0]=a[i-1][n-1];
                for(j=1;j<n;++j)
                    a[i][j]=a[i-1][j-1];;
            }
            ci>>=1;
        }
        
        for(p=1;p<=m;++p)
        {
            for(i=0;i<n;++i)
            {
                t[i]=0;
                t1=(i-p+n)%n;
                t[i]=(t[i]+f[t1])%mod;
                t2=(i+p)%n;
                if(t1!=t2)
                    t[i]=(t[i]+f[t2])%mod;
            }
            for(i=0;i<n;++i)
                f[i]=t[i];
        }
        return f[0];
    }
    
    int main(){
        
        //freopen("T3.in","r",stdin);
        //freopen("T3.out","w",stdout);
        
        read(n); read(m);
        printf("%lld",dp());
    }
    T3

    11.02 晚上

    T1 set

    无解是骗人的...

    求出在mod n 意义下的前缀和,算上$sum_0$一共有最多有n+1个取值

    一定有两个相等,输出两个之间的ans即可

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <iostream>
    #define ll long long
    #define rint register int
    #define mem(a,b) memset(a,b,sizeof(a))
    using namespace std;
    const int N=1000006;
    inline void read(int &x)
    {
        x=0; int f=1;char ch=getchar();
        while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        x*=f;
    }
    
    int n;
    int v[N],pr[N];
    int pos[N];
    
    int main(){
        
        rint i,j;
        
        read(n);
        for(i=1;i<=n;++i)
            read(v[i]);
        mem(pos,-1);
        pos[0]=0;
        for(i=1;i<=n;++i)
        {
            pr[i]=(pr[i-1]+v[i])%n;
            if(pos[pr[i]]!=-1)
            {
                printf("%d
    ",i-pos[pr[i]]);
                for(j=pos[pr[i]]+1;j<=i;++j)
                    printf("%d ",j);
                printf("
    ");
                break;
            }
            pos[pr[i]]=i;
        }
    }
    T1

    T2 read

    我还以为是什么高级数学题

    结果...

    很显然是让求最多出现次数的书出现了多少次

    那么先 利用有用的最大出现次数一定>$frac{n+1}{2}$的性质

    设 id=0,cnt=0

    扫到cnt=0,就id=当前位置值,cnt=1

    if(cnt>0)

    如果当前v不等于id,--cnt

    否则++cnt

    扫到最大值的编号id,但是cnt不准

    所以再扫一遍,求出出现次数

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <iostream>
    #define ll long long
    #define rint register int
    #define mem(a,b) memset(a,b,sizeof(a))
    using namespace std;
    const int N=1000006;
    inline void read(int &x)
    {
        x=0; int ff=1; char q=getchar();
        while(q<'0'|q>'9') { if(q=='-') ff=-1; q=getchar(); }
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
        x*=ff;
    }
    
    int n,m,K;
    int c[1006],X[1006],Y[1006],Z[1006];
    
    int main(){
        
        rint i,j;
        
        read(m); read(K);
        for(i=1;i<=m;++i) read(c[i]);
        for(i=1;i<=m;++i) read(X[i]);
        for(i=1;i<=m;++i) read(Y[i]);
        for(i=1;i<=m;++i) read(Z[i]);
        int maxp=(1<<K)-1,id=-2e9,cnt=0,an; n=0; ll las;
        for(i=1;i<=m;++i)
        {
            ++n; las=X[i];
            if(cnt==0)
                id=las,cnt=1;
            else
            {
                if(las!=id)
                    --cnt;
                else
                    ++cnt;
            }
            for(j=1;j<c[i];++j)
            {
                las=(las*Y[i]+Z[i])&maxp;
                ++n;
                if(cnt==0)
                    id=las,cnt=1;
                else
                {
                    if(las!=id)
                        --cnt;
                    else
                        ++cnt;
                }
            }
        }
        n=0; cnt=0;
        for(i=1;i<=m;++i)
        {
            ++n; las=X[i];
            if(las==id) ++cnt;
            for(j=1;j<c[i];++j)
            {
                las=(las*Y[i]+Z[i])&maxp;
                ++n;
                if(las==id) ++cnt;
            }
        }
        an=cnt-1-(n-cnt);
        if(an<0) an=0;
        cout<<an;
    }
    T2

    T3 race

    考试直接上01trie,然后就懵逼了...

    正解:

    把求$x^2$转化成求前面比他大的数两两配对的对数

    然后发现在01trie上行走,每到一位有$2^{m-1}$天左边比右边大,有$2^{m-1}$天右边比左边大

    设当前到了第i个人,$f_i$为到了01trie上第i位 要走儿子的对立儿子的size

    $$ans=sum_{2*f_i*f_k*2^{m-2}} 的异或和 $$

    $2*f_i*f_k$是在枚举有序对

    $2^{m-2}$是在求交集的个数

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rint register int
    using namespace std;
    const int mod=1e9+7;
    inline void read(int &x)
    {
        x=0; int ff=1; char q=getchar();
        while(q<'0'||q>'9') { if(q=='-') ff=-1; q=getchar(); }
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
        x*=ff;
    }
    const int N=200006;
    
    int n,m;
    int A[N];
    ll an;
    int cnt[42];
    ll f[2][2006];
    
    struct trie
    {
        int sum;
        trie *ch[2];
        trie(){sum=0;ch[0]=ch[1]=NULL;}
    }tong[N*30],*root;
    int size;
    void add(int vv)
    {
        ++root->sum;
        trie *now=root; int i,tt;
        for(i=m-1;~i;--i)
        {
            tt=((1<<i)&vv)>>i;
            if(now->ch[tt]==NULL)
                now->ch[tt]=&tong[size++];
            now=now->ch[tt];
            ++now->sum;
        }
    }
    void dfs(trie *x,ll pr,ll sum)
    {
        if(x->ch[0]==NULL&&x->ch[1]==NULL)
        {
            an^=sum;
            return ;
        }
        int tt;
        if(x->ch[0]!=NULL)
        {
            tt=(x->ch[1]==NULL?0:x->ch[1]->sum);
            dfs(x->ch[0],(pr+tt)%mod,(sum+1LL*tt*(pr+tt)%mod*(1<<(m-1))%mod)%mod);
        }
        if(x->ch[1]!=NULL)
        {
            tt=(x->ch[0]==NULL?0:x->ch[0]->sum);
            dfs(x->ch[1],(pr+tt)%mod,(sum+1LL*tt*(pr+tt)%mod*(1<<(m-1))%mod)%mod);
        }
    }
    
    int main(){
        
        //freopen("T3.in","r",stdin);
        //freopen("T3.out","w",stdout);
        
        rint i,j,k; int tt,sum,now,pr,q1;
        
        read(n); read(m);
        for(i=1;i<=n;++i)
            read(A[i]);
        root=&tong[size++];
        for(i=1;i<=n;++i)
            add(A[i]);
        dfs(root,0,0);
        cout<<an;
    }
    T3

    11.02早上

    T1 hanoi

    它不一定是在中间m-2个柱子上均匀铺开最优...

    $f_{i,j}$ 表示i个盘子j个柱子的最小次数

    $$ f_{i,j}=min(f_{k,j}+f_{i-k,j-1})$$

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <iostream>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ll long long
    #define rint register int
    using namespace std;
    void read(int &x)
    {
        x=0; char q=getchar();
        while(q<'0'||q>'9') q=getchar();
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
    }
    
    int n,m;
    ll f[106][106];
    
    int main(){
        
        rint i,j,k;
        
        read(n); read(m);
        mem(f,127);
        for(j=3;j<=m;++j)
            f[1][j]=1;
        for(i=2;i<=n;++i)
            f[i][3]=f[i-1][3]*2+1;
        for(i=2;i<=n;++i)
            for(j=4;j<=m;++j)
                for(k=1;k<i;++k)
                    f[i][j]=min(f[i][j],f[k][j]*2+f[i-k][j-1]);
        cout<<f[n][m];
    }
    T1

    T2 rank

    贪心就行了

    如果rank和rank+1后面的位置仍然满足大小关系

    说明这一位可以相等,解决纠纷留到下一次

    否则必须++

    最后大于26个取值就不合法...

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <iostream>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ll long long
    #define rint register int
    using namespace std;
    void read(int &x)
    {
        x=0; char q=getchar();
        while(q<'0'||q>'9') q=getchar();
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
    }
    const int N=200006;
    
    int n;
    int ran[N],pos[N];
    int an[N];
    
    int main(){
        
        rint i;
        
        read(n);
        for(i=1;i<=n;++i)
            read(ran[i]),pos[ran[i]]=i;
        an[pos[1]]=0;
        for(i=1;i<n;++i)
        {
            if(ran[pos[i]+1]<ran[pos[i+1]+1])
                an[pos[i+1]]=an[pos[i]];
            else
                an[pos[i+1]]=an[pos[i]]+1;
        }
        int ff=0;
        for(i=1;i<=n;++i)
            if(an[i]>=26)
                ff=1;
        if(ff)
            puts("-1");
        else
            for(i=1;i<=n;++i)
                printf("%c",an[i]+'a');
    }
    T2

    T3 tree

    又是两遍dfs的傻逼题...

    $f_{x}$ 表示从x走到父亲的期望次数

    转移方程经过一波化简后就会变成整数

    没有分数...

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ll long long
    #define rint register int
    using namespace std;
    void read(int &x)
    {
        x=0; char q=getchar();
        while(q<'0'||q>'9') q=getchar();
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
    }
    const int mod=1e9+7;
    const int N=100006;
    int first[N],nt[N<<1],ver[N<<1],e;
    void addbian(int u,int v)
    {
        ver[e]=v;
        nt[e]=first[u];
        first[u]=e++;
    }
    
    int n,Q;
    int maxk;
    ll f[N],g[N],sumf[N][21],sumg[N][21];
    int st[N][21];
    
    int fa[N],dep[N];
    void dfs1(int x)
    {
        f[x]=1;
        int i;
        for(i=first[x];i!=-1;i=nt[i])
            if(ver[i]!=fa[x])
            {
                fa[ver[i]]=x;
                dep[ver[i]]=dep[x]+1;
                dfs1(ver[i]);
                f[x]=(f[x]+f[ver[i]]+1)%mod;
            }
    }
    void dfs2(int x)
    {
        int i;
        for(i=first[x];i!=-1;i=nt[i])
            if(ver[i]!=fa[x])
            {
                if(fa[x]!=-1) g[ver[i]]=1;
                g[ver[i]]=(g[ver[i]]+g[x]+1+(f[x]-1-f[ver[i]]-1))%mod;
                dfs2(ver[i]);
            }
    }
    void ST()
    {
        rint i; int j;
        while((1<<maxk)<=n) ++maxk; --maxk;
        mem(st,-1);
        for(i=1;i<=n;++i)
            st[i][0]=fa[i],sumf[i][0]=f[i],sumg[i][0]=g[i];
        for(j=1;(1<<j)<=n;++j)
            for(i=1;i<=n;++i)
                if(st[i][j-1]!=-1)
                    st[i][j]=st[st[i][j-1]][j-1],
                    sumf[i][j]=(sumf[i][j-1]+sumf[st[i][j-1]][j-1])%mod,
                    sumg[i][j]=(sumg[i][j-1]+sumg[st[i][j-1]][j-1])%mod;
    }
    int LCA(int x,int y)
    {
        if(dep[x]<dep[y]) x^=y,y^=x,x^=y;
        int j;
        for(j=maxk;~j;--j)
            if(dep[x]-(1<<j)>=dep[y])
                x=st[x][j];
        if(x==y) return x;
        for(j=maxk;~j;--j)
            if(st[x][j]!=-1&&st[x][j]!=st[y][j])
                x=st[x][j],y=st[y][j];
        return fa[x];
    }
    ll getf(int x,int y)
    {
        if(dep[x]<=dep[y]) return 0;
        ll an=0; int j;
        for(j=maxk;~j;--j)
            if(dep[x]-(1<<j)>=dep[y])
                an=(an+sumf[x][j])%mod,x=st[x][j];
        return an;
    }
    ll getg(int x,int y)
    {
        if(dep[x]<=dep[y]) return 0;
        ll an=0; int j;
        for(j=maxk;~j;--j)
            if(dep[x]-(1<<j)>=dep[y])
                an=(an+sumg[x][j])%mod,x=st[x][j];
        return an;
    }
    
    int main(){
        
        //freopen("T3.in","r",stdin);
        
        rint i; int tin1,tin2,tt;
        mem(first,-1);
        
        read(n); read(Q);
        for(i=1;i<n;++i)
        {
            read(tin1); read(tin2);
            addbian(tin1,tin2);
            addbian(tin2,tin1);
        }
        fa[1]=-1; dfs1(1);
        dfs2(1);
        ST();
        
        /*printf("
    ");
        for(i=1;i<=n;++i)
            printf("%lld ",f[i]);
        printf("
    ");
        for(i=1;i<=n;++i)
            printf("%lld ",g[i]);
        printf("
    ");*/
        
        for(i=1;i<=Q;++i)
        {
            read(tin1); read(tin2);
            tt=LCA(tin1,tin2);
            //printf("%d %d %d
    ",tin1,tin2,tt);
            printf("%lld
    ",(getf(tin1,tt)+getg(tin2,tt))%mod);
        }
    }
    T3

    还有一些,不想写了....

    最近老是犯一些智障错误

    正解不会,暴力打挂...

    我也很无奈啊...

  • 相关阅读:
    第三方登录原理
    django-rest-framework之 json web token方式完成用户认证
    HTTP Basic Authentication认证
    python 创建虚拟环境
    scrapy pipeline
    beautifulsoup 安装
    scrapy 安装
    Jmeter 安装
    css中的行高line-height
    html块级元素与行内元素
  • 原文地址:https://www.cnblogs.com/A-LEAF/p/7780567.html
Copyright © 2020-2023  润新知