1115练习赛

T1 变量

 贪心的搞,即可。

#include<bits/stdc++.h>
using namespace std;
#define re register int
int n,k,ans,a[100005];
priority_queue<int>Q;
signed main()
{
    scanf("%d%d",&n,&k);
    for(re i=1;i<=n;++i)scanf("%d",&a[i]);
    sort(a+1,a+1+n);
    n=unique(a+1,a+1+n)-a-1;
    for(re i=2;i<=n;++i)Q.push(a[i]-a[i-1]);
    k--;ans=a[n]-a[1];
    while(k>0&&!Q.empty())ans-=Q.top(),Q.pop(),k--;
    printf("%d\n",ans);
    return 0;
}

T2 凸

1<=n<=100,bi<=1e9

 将n^5状态压一压。

#include<bits/stdc++.h>
using namespace std;
#define re register int
#define LL long long
const int mo=1e9+7;
int ans=1, a[105], n;
struct node{int f,y,d;};
bool operator<(const node&p,const node&q){return p.f==q.f?p.y==q.y?p.d<q.d:p.y<q.y:p.f<q.f;}
map<node,int>chk[105];
inline int DFS(int pos,int f,int y,int g)
{
    if(pos==n+1)return 1;
     node tp=(node){f,y,g};
    if(chk[pos].count(tp))return chk[pos][tp];
    int ret=0;
    if(a[pos]-a[pos-1]>=f)ret+=DFS(pos+1,a[pos]-a[pos-1],y,g);
    if(a[pos]-a[y]>=g)ret+=DFS(pos+1,a[pos]-a[y],pos-1,f);
    return chk[pos][tp]=ret%mo;
}
signed main()
{
    scanf("%d",&n);
    for(re i=1;i<=n;++i)scanf("%d",&a[i]);
    sort(a+1,a+1+n);
    int i=1;
    for(;i<=n&&a[i]==a[1];++i)ans=1LL*ans*i%mo;
    printf("%lld\n",1LL*ans*DFS(i,0,i-1,0)%mo);
    return 0;
}

值得注意的是,map这种东西,用结构体时,一定要记得将每个变量都要比较,不然他就会合在一起。

kzsn原本可以AC的,就因为调map这玩意儿!!!切记。

T3 字典树

1<=n<=20,|si|<=50

 是一道容斥的题。

这道题的答案是不同的前缀个数,那么就可以容斥了!

1个的前缀数量-2个的公共前缀数量+3个的公共前缀数量......

#include<bits/stdc++.h>
using namespace std;
#define re register int
const int mo=1e9+7;
int len[55], n, ans, sum, fac[2005];
char ch[55][55];
signed main()
{
    fac[0]=1;for(re i=1;i<=2000;++i)fac[i]=(fac[i-1]<<1)%mo;
    scanf("%d",&n);
    for(re i=1;i<=n;++i)
    {
        scanf("%s",ch[i]+1);
        len[i]=strlen(ch[i]+1);
        for(re j=1;j<=len[i];++j)
        sum+=(ch[i][j]=='?');
    }
    ans=fac[sum];
    int mxs=(1<<n)-1;
    for(re s=1;s<=mxs;++s)
    {
        int temp=sum, minlen=100, jg=0, pre=0;
        for(re i=0;i<n;++i)
        if(s&(1<<i))
        {
            minlen=min(minlen, len[i+1]);
            jg^=1;
        }
        for(re i=1;i<=minlen;++i)
        {
            int f1=0,f0=0;
            for(re j=0;j<n;++j)
            if(s&(1<<j))
            {
                if(ch[j+1][i]=='1')f1=1;
                if(ch[j+1][i]=='0')f0=1;
                if(ch[j+1][i]=='?')temp--;
            }
            if(f1&&f0)break;
            if(!f1&&!f0)pre++;
            ans+=(jg?1:-1)*fac[pre+temp]%mo;
            ans%=mo;
        }
    }
    printf("%d\n",(ans%mo+mo)%mo);
}

 

posted @ 2021-11-15 21:35  kzsn  阅读(45)  评论(0编辑  收藏  举报