文章目录
题目
A - Broken Keyboard
#include<bits/stdc++.h>
using namespace std;
bool vis[26];
int main(){
int n;
scanf("%d",&n);
while(n--){
memset(vis,false,sizeof(vis));
string s,ans;
cin>>s;
int cur=0;
while(cur<s.size()){
char c=s[cur];
int cnt=0;
while(s[cur]==c){
cnt++;
cur++;
}
if(cnt&1&&!vis[c-'a']){
ans+=c;
vis[c-'a']=true;
}
}
sort(ans.begin(),ans.end());
cout<<ans<<endl;
}
}
B - Binary Palindromes
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;
scanf("%d",&t);
while(t--){
int n;
vector<int>vec;
scanf("%d",&n);
int cnt[2]={0,0};
int Pair=0;
for(int i=1;i<=n;i++){
string s;
cin>>s;
Pair+=s.size()/2;
vec.push_back(s.size());
for(int i=0;i<s.size();i++){
cnt[s[i]-'0']++;
}
}
if(Pair>cnt[0]/2+cnt[1]/2)cout<<n-1<<endl;
else cout<<n<<endl;
}
}
C - Minimize The Integer
奇数和偶数分开,类似于归并排序?
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;
scanf("%d",&t);
while(t--){
string s,o,e,ans;
cin>>s;
for(int i=0;i<s.size();i++){
if((s[i]-'0')&1)o+=s[i];
else e+=s[i];
}
int p1=0,p2=0;
while(p1!=o.size()||p2!=e.size()){
if(p1==o.size())ans+=e[p2++];
else if(p2==e.size())ans+=o[p1++];
else if(o[p1]<e[p2])ans+=o[p1++];
else ans+=e[p2++];
}
cout<<ans<<endl;
}
}
D - Salary Changing
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,s,curs;
const ll maxn=2e5+10;
pair<ll,ll>vec[maxn];
ll v[maxn];
bool check(ll mid){
if(mid==s+1)return false;
ll sz=0;
for(ll i=0;i<n;i++){
if(vec[i].second>=mid)v[sz++]=vec[i].first;
}
if(sz<=n/2)return false;
ll ans=0;
for(ll i=1;i<=n/2+1;i++){
if(v[sz-i]<mid){
ans+=mid-v[sz-i];
}
}
return ans<=curs;
}
int main(){
ll t;
scanf("%lld",&t);
while(t--){
scanf("%lld%lld",&n,&s);
curs=s;
for(ll i=0;i<n;i++){
ll a,b;
scanf("%lld%lld",&a,&b);
vec[i]=make_pair(a,b);
curs-=vec[i].first;
}
sort(vec,vec+n);
ll l=vec[n/2].first,r=s+1;
while(r-l>1){
ll mid=(r+l)>>1;
if(check(mid))
l=mid;
else
r=mid;
}
cout<<l<<endl;
}
}
E - Voting
从后往前扫,有限队列里为还没有买通的人,如果优先队列的大小大于当前允许不被买通的人数,则需要买通一部分人,直到二者相等。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=2e5+10;
vector<pair<ll,ll> >vec;
int main(){
ll t;
scanf("%lld",&t);
while(t--){
vec.clear();
priority_queue<ll,vector<ll>,greater<ll> >q;
ll n;
scanf("%lld",&n);
for(ll i=1;i<=n;i++){
ll x,y;
scanf("%lld%lld",&x,&y);
vec.push_back(make_pair(x,y));
}
ll ans=0;
sort(vec.begin(),vec.end());
ll cur=vec.size()-1;
while(cur>=0){
ll x=vec[cur].first;
q.push(vec[cur].second);
cur--;
while(cur>=0&&vec[cur].first==x){
q.push(vec[cur].second);
cur--;
}
while(q.size()>n-x){
ans+=q.top();
q.pop();
}
}
cout<<ans<<endl;
}
}
F - Red-White Fence
orz,将dp优化为组合数学的问题,然后用多项式卷积求解
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const ll maxn=3e5+10;
ll qpow(ll x,ll y)
{
ll res=1;
while(y)
{
if(y&1) res=res*x%mod;
x=x*x%mod;
y>>=1;
}
return res;
}
ll mul(ll x,ll y){
return x*y%mod;
}
ll fac[maxn<<2],ifac[maxn<<2],pw[maxn<<2],ans[maxn<<2];
void init()
{
fac[0]=pw[0]=ifac[0]=1;
for(ll i=1;i<maxn;i++)
fac[i]=mul(fac[i-1],i),pw[i]=mul(pw[i-1],2);
ifac[maxn-1]=qpow(fac[maxn-1],mod-2);
for(ll i=maxn-2;i;i--)
ifac[i]=mul(ifac[i+1],i+1);
}
ll c(ll n,ll m){
if(n<m)return 0;
return mul(fac[n],mul(ifac[n-m],ifac[m]));
}
ll r[maxn<<2];
void ntt(ll *x,ll lim,ll opt)
{
ll i,j,k,m,gn,g,tmp;
for(i=0;i<lim;++i)
if(r[i]<i)
swap(x[i],x[r[i]]);
for(m=2;m<=lim;m<<=1)
{
k=m>>1;
gn=qpow(3,(mod-1)/m);
for(i=0;i<lim;i+=m)
{
g=1;
for(j=0;j<k;++j,g=g*gn%mod)
{
tmp=x[i+j+k]*g%mod;
x[i+j+k]=(x[i+j]-tmp+mod)%mod;
x[i+j]=(x[i+j]+tmp)%mod;
}
}
}
if(opt==-1)
{
reverse(x+1,x+lim);
ll inv=qpow(lim,mod-2);
for(i=0;i<lim;++i)
x[i]=x[i]*inv%mod;
}
}
ll A[maxn<<2],B[maxn<<2],C[maxn<<2];
ll cnt[maxn<<2];
int main()
{
ll n,k;
init();
scanf("%lld%lld",&n,&k);
ll len=1;
while(len<(n<<1)) len<<=1;
for(ll i=1;i<=n;i++){
ll x;
scanf("%lld",&x);
cnt[x]++;
}
for(ll i=1;i<=k;i++){
ll l;
scanf("%lld",&l);
ll c1=0,c2=0;
for(ll j=1;j<l;j++){
if(cnt[j]==1)c1++;
else if(cnt[j]>=2)c2++;
}
for(ll j=0;j<=len;j++){B[j]=c(c2*2,j);
A[j]=mul(c(c1,j),pw[j]);
}
for(ll j=0;j<len;++j)
r[j]=(j&1)*(len>>1)+(r[j>>1]>>1);
ntt(A,len,1);ntt(B,len,1);
for(ll j=0;j<len;++j)
C[j]=A[j]*B[j]%mod;
ntt(C,len,-1);
for(ll j=0;j<=n;j++)
ans[l+j+1]=(ans[l+j+1]+C[j])%mod;
}
ll q;
scanf("%lld",&q);
for(ll i=1;i<=q;i++){
ll x;
scanf("%lld",&x);
printf("%lld\n",ans[x/2]);
}
return 0;
}