这场edu有点简单……
所以题目可能也有点奇奇怪怪的。
A.随意构造一下,可以发现只有当填满都不行时才可能无解。
#include<bits/stdc++.h> using namespace std; int n,k,a[105][105]; inline int read(){ int f=1,x=0;char ch; do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9'); do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9'); return f*x; } int main(){ n=read();k=read(); if(n*n<k){puts("-1");return 0;} for(int i=1;i<=n&&k;i++){ a[i][i]=1; if(k==1)break; k--; for(int j=i+1;j<=n&&k>1;j++)a[i][j]=a[j][i]=1,k-=2; } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++)printf("%d ",a[i][j]); puts(""); } }
B.扫一遍就行了……
#include<bits/stdc++.h> #define N 200005 using namespace std; vector<int> b; int a[N];int n,now=0; inline int read(){ int f=1,x=0;char ch; do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9'); do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9'); return f*x; } int main(){ n=read(); for(int i=1;i<=n;i++){ a[i]=read();if(a[i]==0)b.push_back(i); } for(int i=1;i<=n;i++){ if(now+1<b.size()&&abs(b[now]-i)>abs(b[now+1]-i))++now; printf("%d ",abs(i-b[now])); } }
C.当时想出了倍数构造,但是有一点死活过不去……
加了个极大值特判过了……
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll n,k,ans=1,m; int main(){ ios::sync_with_stdio(false); cin>>n>>k; m=n/(k*(k+1)/2); if(!m||k>143850290){puts("-1");return 0;} for(ll j=1;j*j<=n;j++){ if(n%j==0){ if(j<=m&&j>ans)ans=j;if(n/j<=m&&(n/j)>ans)ans=n/j; } } for(int i=1;i<k;i++)cout<<i*ans<<' '; n-=ans*(k-1)*k/2; cout<<n<<endl; }
D.答案显然可以二分。那么二分判断下是否可行就行。
#include<bits/stdc++.h> #define N 1000010 using namespace std; int n,m,k,a[N]; char s[N]; inline bool check(int x){ int lx=0,ans=1; for(int i=1;i<=m;i++)if(a[i]-a[lx]>x)lx=i-1,++ans; return ans>k; } int main(){ int maxl=0; scanf("%d ",&k);gets(s+1);n=strlen(s+1);s[n]=' '; for(int i=1;i<=n;i++){ if(s[i]=='-'||s[i]==' '){a[++m]=i;maxl=max(maxl,i-a[m-1]);} } int l=maxl,r=n; while(l<=r){ int mid=(l+r)>>1; if(check(mid))l=mid+1; else r=mid-1; } printf("%d ",l); }
E.题解给了个带log的dp,被我记忆化水过去了……
#include<bits/stdc++.h> using namespace std; long long n,k;string s; bool dp[1010][1010]; bool dfs(int u,int v){ if(u==n&&abs(v)==k)return 1; if(u==n||abs(v)>=k)return 0; if(dp[u][v])return 0; dp[u][v]=1; if(s[u]=='W')return dfs(u+1,v+1); if(s[u]=='D')return dfs(u+1,v); if(s[u]=='L')return dfs(u+1,v-1); if(dfs(u+1,v+1)){s[u]='W';return 1;} if(dfs(u+1,v)){s[u]='D';return 1;} if(dfs(u+1,v-1)){s[u]='L';return 1;} return 0; } int main(){ cin>>n>>k;cin>>s; if(!dfs(0,0))puts("NO"); else cout<<s<<endl; }
F.按照题解的式子推一样的,具体看官方题解吧。
#include<bits/stdc++.h> #define N 1000005 #define yql 1000000007 using namespace std; const int lim=1e5+1; int n,cnt[N],a[N],ans[N],p[N]; inline int read(){ int f=1,x=0;char ch; do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9'); do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9'); return f*x; } int main(){ p[0]=1;for(int i=1;i<=lim;i++)p[i]=(p[i-1]<<1)%yql; n=read(); for(int i=1;i<=n;i++)a[read()]++; for(int i=1;i<=lim;i++)for(int j=i+i;j<=lim;j+=i)a[i]+=a[j]; for(int i=lim;i;i--){ ans[i]=p[a[i]]-1; for(int j=i+i;j<=lim;j+=i){ ans[i]-=ans[j]; if(ans[i]<0)ans[i]+=yql; } } printf("%d ",ans[1]); }
G.用动态开点线段树维护ST表(辣鸡cf怎么这么喜欢动态开点)
有点问题留坑待补。
#include<bits/stdc++.h> #define N 100005 #define M 10000005 #define inf 2147483640 using namespace std; int n,m,q,a[N],st[20][N],lg[N]; int tagv[M],val[M],ls[M],rs[M],cnt=1,mn=2e9; inline int rmq(int l,int r){ int len=r-l+1,t=lg[len]; return min(st[t][l],st[t][(r-1<<t)+1]); } inline int query(int l,int r){ int len=r-l+1;if(len>=n)return mn; if((l-1)/n==(r-1)/n)return rmq((l-1)%n+1,(r-1)%n+1); else return min(rmq((l-1)%n+1,n),rmq(1,(r-1)%n+1)); } inline void pushup(int o,int l,int r){ if(~tagv[o])val[o]=tagv[o]?tagv[o]:query(l,r); else val[o]=min(val[ls[o]],val[rs[o]]); } inline void pushdown(int o,int l,int r){ if(!ls[o])ls[o]=++cnt;if(!rs[o])rs[o]=++cnt; if(~tagv[o]){ int mid=(l+r)>>1; tagv[ls[o]]=tagv[o];pushup(ls[o],l,mid); tagv[rs[o]]=tagv[o];pushup(rs[o],mid+1,r); } } void change(int o,int l,int r,int ql,int qr,int v){ if(ql<=l&&r<=qr){tagv[o]=v;return;} int mid=(l+r)>>1;pushdown(o,l,r);tagv[o]=-1; if(ql<=mid)change(ls[o],l,mid,ql,qr,v); if(qr>mid)change(rs[o],mid+1,r,ql,qr,v); pushup(o,l,r); } int query(int o,int l,int r,int ql,int qr){ if(ql<=l&&r<=qr)return val[o]; int mid=(l+r)>>1;pushdown(o,l,r); int ans=inf; if(ql<=mid)ans=min(ans,query(ls[o],l,mid,ql,qr)); if(qr>mid)ans=min(ans,query(rs[o],mid+1,r,ql,qr)); return ans; } inline int read(){ int f=1,x=0;char ch; do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9'); do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9'); return f*x; } inline void initrmq(){ for(int j=1;j<20;++j)for(int i=1;i<=n;++i) if(i+(1<<j)-1<=n)st[j][i]=min(st[j-1][i],st[j-1][i+(1<<j-1)]); } int main(){ n=read();m=read(); for(int i=1;i<=n;i++){ a[i]=read();mn=min(mn,a[i]);st[0][i]=a[i]; } for(int i=2;i<=n;++i)lg[i]=lg[i>>1]+1; initrmq(); q=read();pushup(1,1,n*m); while(q--){ int opt=read(),l=read(),r=read(); if(opt==1){ int v=read();change(1,1,n*m,l,r,v); } else printf("%d ",query(1,1,n*m,l,r)); } return 0; }