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); }