好多考试....

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\n",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\n",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\n",an);
    for(j=0;j<=m;++j)
        an=(an+f[n][j])%mod;
    //printf("ho1an=%lld\n",an);
    // bl\wh
    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;
    // 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=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
    // wh/bl
    // bl\wh
    // 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\n",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\n",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\n",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\n",l0,r0);
    for(i=l0;i<=r0;++i)
        t4[i]+=2;
    if(l0==0) blnum+=1;
    if(r0==n) whnum+=1;
    
    //printf("prpran=%lld\n",an);
    
    if(blnum) an=(an-blnum+1+mod)%mod;
    if(whnum) an=(an-whnum+1+mod)%mod;
    
    //printf("pran=%lld\n",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\n",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("\n");*/
    }
    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("\n");
    for(i=0;i<n;++i)
    {
        for(j=0;j<n;++j)
            printf("%lld ",a[i][j]);
        printf("\n");
    }
    printf("\n");*/
    
    ci=m/n; m=m-n*ci;
    //printf("ci=%d\n",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\n",i-pos[pr[i]]);
            for(j=pos[pr[i]]+1;j<=i;++j)
                printf("%d ",j);
            printf("\n");
            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("\n");
    for(i=1;i<=n;++i)
        printf("%lld ",f[i]);
    printf("\n");
    for(i=1;i<=n;++i)
        printf("%lld ",g[i]);
    printf("\n");*/
    
    for(i=1;i<=Q;++i)
    {
        read(tin1); read(tin2);
        tt=LCA(tin1,tin2);
        //printf("%d %d %d\n",tin1,tin2,tt);
        printf("%lld\n",(getf(tin1,tt)+getg(tin2,tt))%mod);
    }
}
T3

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

最近老是犯一些智障错误

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

我也很无奈啊...

 

posted @ 2017-11-03 21:22  A_LEAF  阅读(234)  评论(0编辑  收藏  举报