省选模拟30

很不如意,啥也不是

考场上由于题面的pdf是一道一道的没有整合起来,于是我就先看的第三题,然后就弃掉了

心态有些爆炸,但是还是强行的给拉回来了

看T1,明显的感觉到是转化题意,但是不知道怎么办,于是只能硬想,想破头皮走了

T2一开始不知道啥叫对称差,后来想了想就是并集减交集,拿了40分

T1

按位考虑,发现如果这一位是1的话,那么会有\(2^{n-1}\)种方案使得这一位是一,0的任意选,1的选奇数个

那么题意就转化为,一堆数或起来能得到的数的个数

按照最高不同位分开,分类讨论

选两个小于最高位的数,无论如何都不会得到其他的数,就是这里面数的数量

选一个大于的数,如果和下面的数或,也可以得到下面的数的数量

如果是两个上面的数,那么找到下一个1,后面的就任意了,最后取个min就好了

AC_code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
    int s=0,t=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
    while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
    return s*t;
}
const int N=105;
int T,n,l,r,ans;
signed main(){
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    T=read();
    while(T--){
        n=read();l=read();r=read();ans=0;
        if(n==1){printf("%lld\n",r-l+1);continue;}
        if(l==r){printf("1\n");continue;}
        fu(i,60,0){
            if(!(r>>i&1))continue;
            if(l>>i&1){
                r^=(1ll<<i);
                l^=(1ll<<i);
                continue;
            }
            ans+=(1ll<<i)-l;
            // cerr<<ans<<endl;
            int now=i-1;
            while(now>=0&&(!((r>>now)&1)))now--;
            // cerr<<now<<" "<<(r>>now&1)<<endl;
            ans+=min((1ll<<i)-l+(1ll<<now+1),(1ll<<i));
            break;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

T2

如果给你一颗树,那么答案就是\(n \choose 4\)

因为每个四元组只有一种划分可能

那么我们接下来的任务就是求交集

首先两条链没有交集,那么这两条链一定会被另外一条链链接

于是可以利用这条链上的点和边进行容斥,边减去点

交集的话,就是边边-边点+点点

可以枚举第一颗树删除啥,然后染色,在第二颗统计就行了

AC_code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
    int s=0,t=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
    while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
    return s*t;
}
const int N=2005;
int n,ans;
int c[N][N],col[N];
struct TREE{
    struct E{int to,nxt;}e[N*2];
    int head[N],rp;
    void add_edg(int x,int y){e[++rp].to=y;e[rp].nxt=head[x];head[x]=rp;}
    void add(int x,int y,int id){add_edg(x,y);add_edg(y,x);}
    int siz[N][3],fa[N];
    void dfs1(int x,int f,int v){
        col[x]=-1;if(x<=n)col[x]=v;
        for(int i=head[x];i;i=e[i].nxt){
            int y=e[i].to;
            if(y==f)continue;
            dfs1(y,x,v);
        }
    }
    void dfs2(int x,int f){
        siz[x][0]=siz[x][1]=siz[x][2]=0;
        if(~col[x])siz[x][col[x]]++;fa[x]=f;
        for(int i=head[x];i;i=e[i].nxt){
            int y=e[i].to;
            if(y==f)continue;
            dfs2(y,x);
            fo(j,0,2)siz[x][j]+=siz[y][j];
        }
    }
}t1,t2;
int d[3][3];
signed main(){
    freopen("b.in","r",stdin);
    freopen("b.out","w",stdout);
    n=read();
    fo(i,0,2*n){
        c[i][0]=1;
        fo(j,1,i)c[i][j]=c[i-1][j-1]+c[i-1][j];
    }
    fo(i,1,2*n-3)t1.add(read(),read(),i);
    fo(i,1,2*n-3)t2.add(read(),read(),i);
    t1.dfs2(1,0);
    ans+=c[n][4]*2;int res=0;
    fo(x,n+1,2*n-2){
        col[x]=-1;
        for(int i=t1.head[x],now=0;i;i=t1.e[i].nxt,now++){
            int z=t1.e[i].to;
            t1.dfs1(z,x,now);
        }
        t2.dfs2(1,0);
        fo(y,n+1,2*n-2){
            fo(i,0,2)d[0][i]=t2.siz[1][i]-t2.siz[y][i];
            for(int i=t2.head[y],now=0;i;i=t2.e[i].nxt){
                int z=t2.e[i].to;
                if(z==t2.fa[y])continue;
                now++;fo(j,0,2)d[now][j]=t2.siz[z][j];
            }
            fo(i,0,2)fo(j,i+1,2)fo(k,0,2)fo(l,k+1,2){
                res+=c[d[i][k]][2]*c[d[j][l]][2];
                res+=c[d[i][l]][2]*c[d[j][k]][2];
            }
        }
    }
    fo(x,n+1,2*n-2){
        for(int i=t1.head[x],now=0;i;i=t1.e[i].nxt,now++){
            int z=t1.e[i].to;
            t1.dfs1(z,x,now);
        }
        t2.dfs2(1,0);
        fo(y,n+1,2*n-2){
            fo(i,0,2){
                d[0][i]=t2.siz[1][i]-t2.siz[y][i];
                d[1][i]=t2.siz[y][i];
            }
            fo(i,0,1)fo(j,i+1,1)fo(k,0,2)fo(l,k+1,2){
                res-=c[d[i][k]][2]*c[d[j][l]][2];
                res-=c[d[i][l]][2]*c[d[j][k]][2];
            }
        }
    }
    fo(x,n+1,2*n-2){
        t1.dfs1(x,t1.fa[x],0);t1.dfs1(t1.fa[x],x,1);
        t2.dfs2(1,0);
        fo(y,n+1,2*n-2){
            fo(i,0,1)d[0][i]=t2.siz[1][i]-t2.siz[y][i];
            for(int i=t2.head[y],now=0;i;i=t2.e[i].nxt){
                int z=t2.e[i].to;
                if(z==t2.fa[y])continue;
                now++;fo(j,0,1)d[now][j]=t2.siz[z][j];
            }
            fo(i,0,2)fo(j,i+1,2)fo(k,0,1)fo(l,k+1,1){
                res-=c[d[i][k]][2]*c[d[j][l]][2];
                res-=c[d[i][l]][2]*c[d[j][k]][2];
            }
        }
    }
    fo(x,n+1,2*n-2){
        t1.dfs1(x,t1.fa[x],0);t1.dfs1(t1.fa[x],x,1);
        t2.dfs2(1,0);
        fo(y,n+1,2*n-2){
            fo(i,0,2){
                d[0][i]=t2.siz[1][i]-t2.siz[y][i];
                d[1][i]=t2.siz[y][i];
            }
            fo(i,0,1)fo(j,i+1,1)fo(k,0,1)fo(l,k+1,1){
                res+=c[d[i][k]][2]*c[d[j][l]][2];
                res+=c[d[i][l]][2]*c[d[j][k]][2];
            }
        }
    }
    ans-=2*res;
    printf("%lld",ans);
    return 0;
}

T3

不会

posted @ 2022-03-12 21:16  fengwu2005  阅读(48)  评论(0编辑  收藏  举报