# 300iq Contest 1 简要题解

codeforces

## A. Angle Beats

### description

$1 \le n, m \le 100.$

## B. Best Subsequence

### description

$3 \le k \le n \le 2\times 10^5, 1 \le w_i \le 10^9.$

### solution

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=2e5+5;
int n,k,w[N],p[N];
int check(int mid){
int cnt=0,res=0;
for(int i=1;i<=n;++i)if(w[i]<=mid/2)p[++cnt]=i;
if(cnt<=1)return cnt;
for(int i=1;i<cnt;++i)
for(int j=p[i]+1;j<p[i+1];++j)
if(w[j]+max(w[p[i]],w[p[i+1]])<=mid){
++res;break;
}
for(int j=p[cnt]+1;j<=n;++j)
if(w[j]+max(w[p[cnt]],w[p[1]])<=mid)
return cnt+res+1;
for(int j=1;j<p[1];++j)
if(w[j]+max(w[p[cnt]],w[p[1]])<=mid)
return cnt+res+1;
return cnt+res;
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;++i)scanf("%d",&w[i]);
int l=2,r=2e9,res;
while(l<=r){
int mid=l+(r-l>>1);
if(check(mid)>=k)res=mid,r=mid-1;
else l=mid+1;
}
printf("%d\n",res);return 0;
}


## C. Cool Pairs

### description

• $-n \le a_i, b_i \le n$
• $a_{p_1} \le a_{p_2} \le ... \le a_{p_n}, b_{q_1} \le b_{q_2} \le ... \le b_{q_n}$
• 满足$i<j, a_i<b_j$$(i,j)$数量恰好为$k$

$1 \le n \le 3\times 10^5, 0 \le k \le \frac{n(n-1)}{2}.$

### solution

• $a_{p_i}=i-1-n$
• 存在一个$x\in[1,n]$，使$\forall i\in[1,x), b_{q_i}=0, \forall i\in(x,n], b_{q_i}=n$

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=3e5+5;
int n,a[N],b[N],c[N];long long k;
int main(){
scanf("%d%lld",&n,&k);
for(int i=1,x;i<=n;++i)scanf("%d",&x),a[x]=i-1-n,b[i]=n;
for(int i=1,x;i<=n;++i){
scanf("%d",&x);
if(x-1<=k)b[x]=0,k-=x-1;
else{
for(int j=1;j<x;++j)c[j]=a[j];
sort(c+1,c+x);
b[x]=-c[k+1];break;
}
}
puts("Yes");
for(int i=1;i<=n;++i)printf("%d ",a[i]);puts("");
for(int i=1;i<=n;++i)printf("%d ",b[i]);puts("");
return 0;
}


## D. Dates

### description

$1 \le n, t \le 3\times 10^5, 0 \le a_i \le n, 1 \le p_i \le 10^9.$

### solution

$sa_i,sb_i$分别为$a_i$$b_i$的前缀和，那么限制为$sb_R-sb_{L-1}\le sa_{r_R}-sa_{l_L-1}$$sb_R-sa_{r_R}\le sb_{L-1}-sa_{l_L-1}$。再记$c_i=sb_i-sa_{r_i},d_i=sb_{i-1}-sa_{l_i-1}$，限制为$c_R\le d_L$

#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
const int N=3e5+5;
struct segment_tree{
ll op,arr[N],val[N<<2],tag[N<<2];
ll merge(ll x,ll y){return op?max(x,y):min(x,y);}
void build(int x,int l,int r){
if(l==r){val[x]=arr[l];return;}
tag[x]=0;int mid=l+r>>1;
build(x<<1,l,mid);build(x<<1|1,mid+1,r);
val[x]=merge(val[x<<1],val[x<<1|1]);
}
void init(int n,ll _op){
op=_op;build(1,1,n);
}
void modify(int x,int l,int r,int ql,int qr,ll v){
if(l>=ql&&r<=qr){val[x]+=v;tag[x]+=v;return;}
int mid=l+r>>1;
if(ql<=mid)modify(x<<1,l,mid,ql,qr,v);
if(qr>mid)modify(x<<1|1,mid+1,r,ql,qr,v);
val[x]=merge(val[x<<1],val[x<<1|1])+tag[x];
}
ll query(int x,int l,int r,int ql,int qr){
if(l>=ql&&r<=qr)return val[x];
int mid=l+r>>1;
if(qr<=mid)return query(x<<1,l,mid,ql,qr)+tag[x];
if(ql>mid)return query(x<<1|1,mid+1,r,ql,qr)+tag[x];
return merge(query(x<<1,l,mid,ql,qr),query(x<<1|1,mid+1,r,ql,qr))+tag[x];
}
}T1,T2;
int n,m,p[N],id[N];ll sa[N],ans;
bool cmp(int x,int y){return p[x]>p[y];}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i)scanf("%lld",&sa[i]),sa[i]+=sa[i-1];
for(int i=1,l,r;i<=n;++i){
scanf("%d%d%d",&l,&r,&p[i]);id[i]=i;
T1.arr[i]=-sa[r];T2.arr[i]=-sa[l-1];
}
T1.init(n,1);T2.init(n,0);sort(id+1,id+n+1,cmp);
for(int i=1;i<=n;++i)
if(T1.query(1,1,n,id[i],n)<T2.query(1,1,n,1,id[i])){
T1.modify(1,1,n,id[i],n,1);
if(id[i]<n)T2.modify(1,1,n,id[i]+1,n,1);
ans+=p[id[i]];
}
printf("%lld\n",ans);return 0;
}


## E. Expected Value

### description

$2 \le n \le 3000.$

### solution

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=3005;
const int mod=998244353;
int n,m,a[N][N],cnt[N],pos[N],ans[N];
void Inc(int &x,int y){x+=y;x>=mod?x-=mod:x;}
int fastpow(int x,int y){
int res=1;
while(y){if(y&1)res=1ll*res*x%mod;x=1ll*x*x%mod;y>>=1;}
return res;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i)scanf("%*d%*d");
scanf("%d",&m);
for(int i=1,x,y;i<=m;++i){
scanf("%d%d",&x,&y);
Inc(a[x][x],mod-1);Inc(a[y][y],mod-1);
Inc(a[x][y],1);Inc(a[y][x],1);
Inc(a[x][n+1],1);Inc(a[y][n+1],1);
}
for(int i=1;i<=n+1;++i)a[n][i]=0;a[n][n]=1;
for(int i=1;i<=n;++i)
for(int j=1;j<=n+1;++j)
if(a[i][j])++cnt[i];
cnt[0]=1<<30;
for(int i=1;i<=n;++i){
int r=0;
for(int j=i;j<=n;++j)if(a[j][i]&&cnt[j]<cnt[r])r=j;
if(r!=i)swap(a[r],a[i]),swap(cnt[r],cnt[i]);
int inv=fastpow(a[i][i],mod-2),top=0;
for(int j=i;j<=n+1;++j){
a[i][j]=1ll*a[i][j]*inv%mod;
if(a[i][j])pos[++top]=j;
}
for(int j=i+1;j<=n;++j)
if(a[j][i]){
int t=mod-a[j][i];
for(int k=1;k<=top;++k){
if(a[j][pos[k]])--cnt[j];
a[j][pos[k]]=(a[j][pos[k]]+1ll*t*a[i][pos[k]])%mod;
if(a[j][pos[k]])++cnt[j];
}
}
}
for(int i=n;i;--i){
ans[i]=mod-a[i][n+1];
for(int j=i+1;j<=n;++j)
ans[i]=(ans[i]+1ll*(mod-ans[j])*a[i][j])%mod;
}
printf("%d\n",ans[1]);return 0;
}


## F. Free Edges

### description

$1 \le n, m \le 10^5.$

### solution

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1e5+5;
int n,m,fa[N],ans;
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)fa[i]=i;
for(int i=1,x,y;i<=m;++i){
scanf("%d%d",&x,&y);
if(find(x)!=find(y))fa[find(x)]=find(y);
else ++ans;
}
printf("%d\n",ans);return 0;
}


## G.Graph Counting

### description

$1 \le n \le 5\times 10^5.$

### solution

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=5e5+5;
const int mod=998244353;
int n,m,f[N],g[N];
void Inc(int &x,int y){x+=y;x>=mod?x-=mod:x;}
int main(){
scanf("%d",&n);++n;
f[1]=1;f[2]=2;f[3]=5;f[m=4]=7;
while(f[m]<=n)++m,f[m]=3+2*f[m-2]-f[m-4];
for(int i=g[0]=1;i<=n;++i)
for(int j=1;f[j]<=i;++j)
if((j+1>>1)&1)Inc(g[i],g[i-f[j]]);
else Inc(g[i],mod-g[i-f[j]]);
printf("%d\n",(g[n]+mod-1)%mod);
return 0;
}


## H. Hall's Theorem

### description

$1 \le n \le 20, 0 \le k < 2^n.$

### solution

#include<cstdio>
#include<algorithm>
using namespace std;
int n,k,c[23][23],m,a[666],b[666];
int main(){
scanf("%d%d",&n,&k);k=(1<<n)-1-k;
for(int i=c[0][0]=1;i<n;++i)
for(int j=c[i][0]=1;j<=i;++j)
c[i][j]=c[i-1][j]+c[i-1][j-1];
for(int i=n-1;~i;--i)
for(int j=0;j<=i;++j)
if(k>=c[i][j])k-=c[i][j],a[++m]=n-i,b[m]=j+1;
else break;
printf("%d\n",m);
for(int i=1;i<=m;++i)printf("%d %d\n",a[i],b[i]);
return 0;
}


## I. Interesting Graph

For any subset $A$ of $7$ vertices of the graph, there are some two vertices $a, b \in A$ and some vertex $c \notin A$ such that all paths from $a$ to $b$ contain vertex $c$.

$1 \le n, m \le 10^5.$

### solution

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int N=1e5+5;
const int mod=998244353;
int inv[10],C[10],n,m,mrk[N],tot,all,ban[100],dp[7][100],scc,baz[N];
vector<int>E[N],foo[N],bar[N];
inline void Inc(int &x,int y){x+=y;x>=mod?x-=mod:x;}
inline int fastpow(int x,int y){
int res=1;
while(y){if(y&1)res=1ll*res*x%mod;x=1ll*x*x%mod;y>>=1;}
return res;
}
void dfs(int u){
mrk[u]=tot++;
for(int v:E[u]){
if(!~mrk[v])dfs(v);
ban[1<<mrk[u]|1<<mrk[v]]=1;
}
}
int main(){
scanf("%d%d",&n,&m);inv[1]=1;
for(int i=2;i<10;++i)inv[i]=1ll*inv[mod%i]*(mod-mod/i)%mod;
for(int i=1,x,y;i<=m;++i)scanf("%d%d",&x,&y),E[x].push_back(y),E[y].push_back(x);
memset(mrk,-1,sizeof(mrk));
for(int u=1;u<=n;++u)
if(!~mrk[u]){
memset(ban,0,sizeof(ban));tot=0;
dfs(u);all=(1<<tot)-1;
for(int i=1;i<=all;i<<=1)
for(int j=0;j<=all;++j)
if(j&i)
ban[j]|=ban[j^i];
memset(dp,0,sizeof(dp));dp[0][0]=1;
for(int i=0;i<tot;++i)
for(int j=0;j<=all;++j)
if(dp[i][j])
for(int s=all^j,k=s;k;k=(k-1)&s)
if(!ban[k])
Inc(dp[i+1][j|k],dp[i][j]);
vector<int>vec(tot);
for(int i=0;i<tot;++i)vec[i]=dp[i+1][all];
foo[++scc]=vec;
}
sort(foo+1,foo+scc+1);tot=0;
for(int i=1;i<=scc;++i){
if(i==1||foo[i]!=bar[tot])
bar[++tot]=foo[i];
++baz[tot];
}
for(int i=1;i<=n;++i){
C[0]=i;
for(int j=1;j<6;++j)C[j]=1ll*C[j-1]*(i-j+mod)%mod*inv[j+1]%mod;
int res=1;
for(int j=1;j<=tot;++j){
int s=0;
for(int k=0;k<bar[j].size();++k)
Inc(s,1ll*bar[j][k]*C[k]%mod);
res=1ll*res*fastpow(s,baz[j])%mod;
}
printf("%d ",res);
}
puts("");return 0;
}


## J. Jealous Split

### description

$3 \le k \le n \le 10^5, 0 \le a_i \le 5\times 10^4.$

### solution

#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
const int N=1e5+5;
int n,k,a[N],p1[N],t1,p2[N],t2;
int check(ll mid){
ll sum=0;int res=0;
for(int i=1;i<=n;++i){
sum+=a[i];
if(sum>=mid)++res,sum=0;
}
return res;
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;++i)scanf("%d",&a[i]);
ll l=0,r=5e9,res;
while(l<=r){
ll mid=l+r>>1;
if(check(mid)>=k)res=mid,l=mid+1;
else r=mid-1;
}
ll sum=0;
for(int i=1;i<=n;++i){
sum+=a[i];
if(sum>=res)p1[++t1]=i,sum=0;
}
sum=0;
for(int i=n;i;--i){
sum+=a[i];
if(sum>=res+1)p2[++t2]=i,sum=0;
}
puts("Yes");
if(t1==k&&p1[k]==n){
for(int i=1;i<k;++i)printf("%d ",p1[i]);
puts("");return 0;
}
for(int i=1;i<=t1;++i)
if(k-i>=1&&k-i<=t2&&p1[i]+1==p2[k-i]){
for(int j=1;j<=i;++j)printf("%d ",p1[j]);
for(int j=k-i-1;j;--j)printf("%d ",p2[j]-1);
puts("");return 0;
}
return 0;
}


## K. Knowledge

### description

$1 \le |S| \le 3\times 10^5, 1 \le m \le 10^9.$

### solution

#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
using namespace std;
const int mod=998244353;
map<string,string>trans;
map<string,int>state;
string str[15];int tot,n,m;
int f(string s){
string t;
for(int i=0;i<s.size();++i){
t+=s[i];
if(trans.count(t))t=trans[t];
}
return state[t];
}
struct mat{
int a[15][15];
mat(){memset(a,0,sizeof(a));}
int *operator [](int x){return a[x];}
mat operator * (mat b){
mat c;
for(int i=1;i<=tot;++i)
for(int j=1;j<=tot;++j)
for(int k=1;k<=tot;++k)
c[i][k]=(c[i][k]+1ll*a[i][j]*b[j][k])%mod;
return c;
}
}S,T;
int main(){
trans["aa"]="";
trans["baa"]="b";
trans["bbb"]="";
trans["abaa"]="ab";
trans["abab"]="bba";
trans["abba"]="bab";
trans["abbb"]="a";
trans["baba"]="abb";
trans["bbaa"]="bb";
trans["babba"]="bbab";
trans["babbb"]="ba";
trans["bbaba"]="babb";
trans["bbabb"]="aba";
for(int i=1;i<=tot;++i){
S[i][i]=1;
++T[i][f(str[i]+"a")];
++T[i][f(str[i]+"b")];
}
cin>>n>>str[0]>>m;
while(m){if(m&1)S=S*T;T=T*T;m>>=1;}
cout<<S[f("")][f(str[0])]<<endl;
return 0;
}

posted @ 2019-08-22 11:28  租酥雨  阅读(2286)  评论(5编辑  收藏