• 10.27night清北刷题班


    /*
    枚举每个部分的总和,利用前缀和进行检验。
    如果能分成4部分就一定能分成2部分,就筛了一边素数优化。
    清空数组!!!
    */ #include<bits/stdc++.h> #define N 1000001 using namespace std; int prime[N],no[N]={0,1},num[N],sum[N]; int n,m,tot,cur,tmp,flag; char s[N]; bool vis[N]; void pri() { for(int i=2;i<=N;i++) { if(!no[i]) prime[++tot]=i; for(int j=1;j<=tot;j++) { if(i*prime[j]>=N)break; no[i*prime[j]]=1; if(i%prime[j]==0) break; } } } int main() { freopen("divie.in","r",stdin); freopen("divide.out","w",stdout); int T;scanf("%d",&T); pri(); while(T--) { scanf("%s",s+1); n=strlen(s+1);int opt=0; memset(num,0,sizeof num); memset(sum,0,sizeof sum); memset(vis,0,sizeof vis); for(int i=1;i<=n;i++) num[i]=s[i]-'0'; for(int i=1;i<=n;i++) sum[i]=sum[i-1]+num[i],vis[sum[i]]=1; if(sum[n]==0) {printf("YES ");continue;} for(int i=1;i<=min(n,tot);i++) { if(prime[i]>sum[n]) break; if(sum[n]%prime[i]) continue; cur=prime[i];tmp=sum[n]/prime[i]; flag=0; for(int j=1;j<=cur;j++) if(!vis[j*tmp]){flag=1;break;} if(!flag) {opt=1;printf("YES ");break;} } if(opt) continue; printf("NO "); } return 0; }

    /*
    dp[n]表示n个点,每个点都和点1相连,且n个点互相连通的图的个数。
    S[n]总的个数
    g[n]表示n个点,每个点都和点1相连,且不是n个点互相连通的图的个数。
    考虑从除了1之外的n-1个点中选出i-1个点,让这i个点互相连通,而剩下的n-i个点和这i个点没有边相连,互相之间随意连接。
    这个代码5000要跑1.6s,所以后面90%数据打表23333
    100%需要fft优化。
    */
    #include<bits/stdc++.h>
    
    #define N 50001
    #define ll long long
    #define M 998244353
    
    using namespace std;
    ll fac[N]={1,1},inv[N]={1,1},f[N]={1,1};
    ll dp[N],g[N],S[N];
    int n;
    
    ll C(ll a,ll b)
    {
        return fac[a]*inv[b]%M*inv[a-b]%M;
    }
    
    ll kfc(ll x,ll y)
    {
        x=x%M,y=y%M;
        return ((x*y-(ll)(((long double)x*y+0.5)/M)*M)%M+M)%M;
    }
    
    ll ksm(ll a,ll b)
    {
        ll res=1;
        while(b)
        {
            if(b&1) res=kfc(res,a)%M;
            b>>=1; a=kfc(a,a)%M;
        }return res%M;
    }
    
    void init()
    {
        for(int i=2;i<N;i++)
        {
            fac[i]=fac[i-1]*i%M;
            f[i]=(M-M/i)*f[M%i]%M;
            inv[i]=inv[i-1]*f[i]%M;
        }
    }
    
    int main()
    {
        freopen("count.in","r",stdin);
        freopen("count.out","w",stdout);
        cin>>n;init();
        dp[1]=1;g[1]=0;
        for(int i=1;i<=5000;i++) S[i]=ksm(2,(i*(i-1))/2);
        for(int i=2;i<=5000;i++)
        {
            g[i]=0;
            for(int j=1;j<i;j++)
                g[i] =(g[i]+(C(i-1,j-1)*dp[j]%M*S[i-j])%M)%M; 
            dp[i]=(S[i]-g[i]+M)%M;
        }
        cout<<dp[n]<<endl;
        return 0;
    }

    /*
    暴力枚举选哪几条路径
    */
    #include<bits/stdc++.h>
    
    #define N 100007
    #define ll long long
    
    using namespace std;
    ll n,m,ans,cnt,flag,cur;
    ll head[N],deep[N],sum[N],f[N][28];
    ll vis[N],choose[N],W[N];
    struct edge{
        ll u,v,net;
    }e[N<<1];
    struct node{
        int pos,x,y;
    }p[N];
    
    inline ll read()
    {
        int x=0,f=1;char c=getchar();
        while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    inline ll max(ll a,ll b){return a>b?a:b;}
    
    inline void add(int u,int v)
    {
        e[++cnt].v=v;e[cnt].net=head[u];head[u]=cnt;
    }
    
    void DFS(int u,int fa,int c)
    {
        f[u][0]=fa;deep[u]=c;
        for(int i=head[u];i;i=e[i].net)
        {
            int v=e[i].v;
            if(v==fa) continue;
            sum[v]+=sum[u];
            DFS(v,u,c+1);
        }
    }
    
    void get()
    {
        for(int j=1;j<=27;j++) for(int i=1;i<=n;i++)
        f[i][j]=f[f[i][j-1]][j-1];
    }
    
    int lca(int a,int b)
    {
        if(deep[a]<deep[b]) swap(a,b);
        int t=deep[a]-deep[b];
        for(int i=0;i<=26;i++)
         if(t&(1<<i)) a=f[a][i];
          if(a==b) return a;
        for(int i=26;i>=0;i--)
          if(f[a][i]!=f[b][i]) a=f[a][i],b=f[b][i];
        return f[a][0];
    }
    
    ll S(ll a,ll b)
    {
        int res=lca(a,b);
        return sum[a]+sum[b]-2*sum[res]+W[res];
    }
    
    void expand(int i)
    {
        int x=p[i].x,y=p[i].y,res=lca(x,y);
        if(vis[res]) {flag=1;return;}
        while(x!=res)
        {
            if(vis[x])
            {flag=1;break;}
              vis[x]=1;x=f[x][0];
        }
        while(y!=res){if(vis[y]){vis[y]=2;flag=1;}else vis[y]=1;y=f[y][0];}vis[res]=1;
    }
    
    void clear(int i)
    {
        int x=p[i].x,y=p[i].y,res=lca(x,y);
        if(x==res && vis[x]) vis[x]--;
        if(y==res && vis[y]) vis[y]--; 
        while(x!=res){vis[x]=0;x=f[x][0];}
        while(y!=res){if(vis[y])vis[y]--;y=f[y][0];}if(x!=res && y!=res)vis[res]--;    
    }
    
    void dfs(int k,int tot,int lim)
    {
        if(tot==lim)
        {
            flag=0,cur=0;
            memset(vis,0,sizeof vis);
            for(int i=1;i<=m;i++)
            {
                if(choose[i])
                {
                    expand(i);
                    if(flag) return;
                    else cur+=S(p[i].x,p[i].y);
                }
            }
            ans=max(ans,cur);
            return;
        }
        for(int i=k;i<=m;i++)
        {
            if(choose[i]) continue;
            choose[i]=1;dfs(i+1,tot+1,lim);
            choose[i]=0;
            clear(i);
        }
    }
    
    int main() 
    {
        freopen("ly.in","r",stdin);
        int x,y;
        n=read();
        for(int i=1;i<=n;i++) W[i]=sum[i]=read();
        for(int i=1;i<n;i++)
        {
            x=read();y=read();
            add(x,y);add(y,x);
        }
        DFS(1,1,0);get();
        m=read();
        for(int i=1;i<=m;i++)
        {
            p[i].x=read();p[i].y=read();p[i].pos=i;
            ans=max(ans,S(p[i].x,p[i].y));
        }
        for(int i=1;i<=n/2;i++)
        {
            memset(choose,0,sizeof choose);
            memset(vis,0,sizeof vis);
            dfs(1,0,i);
        }
        printf("%lld
    ",ans);
        return 0;
    }
    /*
    10
    1 2 3 4 5 6 7 8 9 10
    10 6
    9 6
    3 1
    6 7
    6 3
    3 8
    8 5
    8 4
    2 6
    4
    2 3
    3 4
    4 5
    9 1
    
    */
    30暴力
  • 相关阅读:
    map初始化
    map
    sort排序
    455分发饼干
    392判断子序列
    vector遍历
    vector删除数据
    VC-进程间通信(InterProcess Communication,IPC)
    Oracle 11g 安装和登录(windows)
    控制台输出宽字符wchar_t的中文显示问题
  • 原文地址:https://www.cnblogs.com/L-Memory/p/9867408.html
Copyright © 2020-2023  润新知