其他分享
首页 > 其他分享> > 2019.8.22(膜你赛)

2019.8.22(膜你赛)

作者:互联网

表示今天是自闭的一天,话说这是我假期里第一次写在学校考试(虽然有的题可能网上都有

今天考试的题目再次属于雅礼集训的题目qwq。

T1:

题目描述(由于我太懒了,所以我直接就贴图了(逃~)):


这道题的思路我在刚开始的时候其实就想到了,但是在写的时候,脑子一抽,没有想到使用并查集进行维护,而且自己在写的时候,稍微在实现时跑偏了,最终只拿到了10分qwq。
这道题其实很简单,就是使用并查集将这不同的数形成连通块,然后查询连通块的个数,最后应用结论:
\[ \text { ans }=2^{n}-2 \]
这样我们就可以十分简单的解决掉这道题。
代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
template <typename type>
void scan(type &x){
    type f=1;x=0;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    x*=f;
}
const int mod=1e9+7;
const int N=1e6+7;
#define ll long long
ll ksm(ll a,ll b){
    ll ans=1;
    while(b){
        if(b&1)ans=(ans*a)%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}
//int gcd(int m,int n)
//    {
//      while (n != 0)
//  {
//    int t = m % n;
//    m = n;
//    n = t;
//  }
//      return m;
//}
//void dfs(){
//  for(int i=1;i<=n;i++){
//      
//  }
//}    
int pre[N],val[N],n,m,cnt,t;
void get_prime(){
    memset(val,0,sizeof(val));
    int cnt=0;
    for(int i=2;i<=1e6+1;i++){
        if(val[i]==0){
            val[i]=i;
            pre[++cnt]=i;
        }
        for(int j=1;j<=cnt;j++){
            if(pre[j]>val[i]||pre[j]>(1e6+1)/i)break;
            val[i*pre[j]]=pre[j];
        }
    }
//  printf("%d\n",cnt);
//  for(int i=1;i<=cnt;i++){
//      printf("%d ",pre[i]);
//  }
}
int vis[N],a[N];
//int vis1[N];
//int num=0;
int fa[N];
int get(int x){
    if(fa[x]==x)return fa[x];
    fa[x]=get(fa[x]);
    return fa[x];
}

int main(){
    freopen("x.in","r",stdin);
    freopen("x.out","w",stdout);
    
    get_prime();
    scan(t);
    while(t--){
        scan(n);
        cnt=0;
        memset(vis,0,sizeof(vis));
//      if(n>15){
        int maxx=0;
        for(int i=1;i<=n;i++){
            scan(a[i]);
            maxx=max(maxx,a[i]);
//          fa[a[i]]=a[i];
        }
        for(int i=1;i<=maxx;i++)fa[i]=i;
        for(int i=1;i<=n;i++){
            if(a[i]==1){
                cnt++;
                continue;
            }
            ll x=a[i],lim=sqrt(a[i]);
//          int flag=0;
            if(val[x]==x){
                continue;
            }
            for(int j=1;pre[j]<=lim&&val[x]!=x;j++){
                if(x%pre[j]!=0)continue;
//              flag=1;
                while(x%pre[j]==0) x/=pre[j];
                if(get(a[i])!=get(pre[j])){
                    fa[get(a[i])]=get(pre[j]);
                }
            }
            if(val[x]==x) fa[get(a[i])]=get(x);
        } 
        for(int i=1;i<=n;i++){
            if(a[i]==1)continue;
            if(vis[get(a[i])]==0){
                cnt++;
                vis[get(a[i])]=1;
            }
        }
        printf("%lld\n",ksm(2,cnt)-2);
//      for(int i=1;i<=n;i++){
//          printf("%d ",fa[a[i]]);
//      }
//      puts("");
//      sort(a+1,a+1+n);
//      for(int i=1;i<=n;i++){
////            scan(a[i]);
//          vis1[a[i]]=1;
//          if(a[i]==1)continue;
//          int flag=0,num=0,flag1=0;
//          for(int j=1;pre[j]<=sqrt(a[i]);j++){
//              if(a[i]%pre[j]!=0)continue;
//              flag1=1;
//              if(vis1[pre[j]])num++;
//              if((a[i]/pre[j])%pre[j]==0&&vis1[pre[j]])break;
//              if(flag==1){
//                  vis[pre[j]]=1;
//              }
//              if(flag==0){
//                  if(vis[pre[j]]==1){
//                      flag=1;
//                  }else{
//                      vis[pre[j]]=1;
//                  }
//              }
//              a[i]/=pre[j];
//          }
//          if(flag1==0)vis[a[i]]=1;
////            if(vis1[a[i]]&&flag1)num++;
//          if(flag)
//          i--,
//          n--;
//          i-=num;
//          n-=num;
//      }
//      printf("%lld\n",(ksm(2,n)-2)%mod);
//      printf("%d\n",n);
//      }else{
//          for(int i=1;i<=n;i++){
//              scan(a[i]);
//          }
//          
//      }
        
    }
    
    
    return 0;
}

无脑T1 qwq

T2

T2打的暴力,直接挂掉>﹏<
先放题目吧:


这道题我,,,,,,不会!
题解告诉我,这是meet in the middle(不会,再见)。
要留代码吗?
算了,留一个std吧(手动狗头)

#include<bits/stdc++.h>
using namespace std;

const int maxn=90+10,maxmask=1<<20/2+1;
int n,m,d,d1,d2,ans;
bitset<maxn> g0[maxn],g1[maxn],dp[maxmask],f[maxmask];

int main(){
    freopen("y.in","r",stdin);
    freopen("y.out","w",stdout);
    scanf("%d%d%d",&n,&m,&d);
    for(int i=1,u,v,c;i<=m;++i){
        scanf("%d%d%d",&u,&v,&c);
        if(c)
            g1[u][v]=g1[v][u]=true;
        else
            g0[u][v]=g0[v][u]=true;
    }
    d2=d/2;d1=d-d2;
    for(int u=n;u;--u){
        for(int i=0;i<maxmask;++i)
            dp[i].reset();
        dp[1][u]=true;
        for(int x=1;x<1<<d1;++x)
            for(int v=1;v<=n;++v)
                if(dp[x][v]){
                    dp[x<<1]|=g0[v];
                    dp[x<<1|1]|=g1[v];
                }
        for(int x=0;x<1<<d1;++x)
            f[x][u]=dp[1<<d1|x].any();
    }
    for(int i=0;i<1<<d1;++i)
        for(int j=0;j<1<<d2;++j)//����dp����״̬������1Ϊ��ͷ��չ������ 
            if((dp[1<<d2|j]&f[i]).any())
                ++ans;
    printf("%d\n",ans);
    return 0;
}

T3,鸽了!

标签:2019.8,22,int,这道题,maxn,include,maxmask,qwq
来源: https://www.cnblogs.com/xishirujin/p/11397038.html