清北刷题冲刺 11-01 p.m
轮换
#include<iostream> #include<cstdio> #include<cstring> #define maxn 1010 using namespace std; int n,p,k,a[maxn],b[maxn],op[maxn][maxn],pos[maxn]; int main(){ freopen("rotate.in","r",stdin);freopen("rotate.out","w",stdout); // freopen("Cola.txt","r",stdin); scanf("%d%d%d",&n,&p,&k); for(int i=1;i<=n;i++)a[i]=i,b[i]=i; for(int i=1;i<=p;i++){ scanf("%d",&op[i][0]); for(int j=1;j<=op[i][0];j++) scanf("%d",&op[i][j]); } for(int i=p;i>=1;i--){ for(int j=1;j<=op[i][0];j++){ pos[j]=b[op[i][j]]; } int w=op[i][1]; for(int j=1;j<=op[i][0];j++){ int x=op[i][j],y=op[i][j+1]; if(j==op[i][0])y=w; a[pos[j]]=y; b[y]=pos[j]; } } for(int i=1;i<=n;i++)printf("%d ",a[i]); return 0; }
区间
#include<iostream> #include<cstdio> #define mod 1000000007 using namespace std; int val[1000010]; int sum[1000010]; int n,a,b,c,d,ans,q,w,e; int qread(){ int i=0; char ch=getchar(); while(ch<'0'||ch>'9') ch=getchar(); while(ch<='9'&&ch>='0'){i=i*10+ch-'0';ch=getchar();} return i; } int main(){ freopen("range.in","r",stdin);freopen("range.out","w",stdout); n=qread(),a=qread(),b=qread(),c=qread(),d=qread(); for(int i=1;i<=n;i++){ val[i]=qread(); if(val[i]>=a&&val[i]<=b&&val[i]>=c&&val[i]<=d) ans++; } for(int i=1;i<=n;i++){ w=e=val[i]; for(int j=i+1;j<=n;j++){ w=w&val[j];e=e|val[j]; if(w<a||e>d) break; if(w<=b&&e>=c) ans++; } while(ans>mod) ans-=mod; } cout<<ans; }
/* 3 2 2 3 3 2 3 3 */ #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #define mod 1000000007 #define maxn 100005 long long cnt; int s[maxn],n,a,b,c,d,sta[maxn][20],sto[maxn][20]; using namespace std; int aska(int l,int r){ int L=r-l+1; int t=log2(L); return sta[l][t]&sta[r-(1<<t)+1][t]; } int asko(int l,int r){ int L=r-l+1; int t=log2(L); return sto[l][t]|sto[r-(1<<t)+1][t]; } int main(){ freopen("range7.in","r",stdin); scanf("%d%d%d%d%d",&n,&a,&b,&c,&d); for(int i=1;i<=n;i++){ scanf("%d",&s[i]); sta[i][0]=sto[i][0]=s[i]; } for(int j=1;j<20;j++) for(int i=1;i<=n;i++) if(i+(1<<j)-1<=n){ sta[i][j]=sta[i][j-1]&sta[i+(1<<j-1)][j-1]; sto[i][j]=sto[i][j-1]|sto[i+(1<<j-1)][j-1]; } for(int i=1;i<=n;i++){ int andsum=s[i],orsum=s[i]; for(int j=i;j<=n;j++){ int L=j,R=n+1;//二分右端点 andsum=aska(i,j); orsum=asko(i,j); while(R-L>1){ int mid=(L+R)>>1; if(aska(i,mid)==andsum&&asko(i,mid)==orsum)L=mid; else R=mid; } if(a<=andsum&&andsum<=b&&c<=orsum&&orsum<=d){ cnt+=L-j+1; } j=L; } } cout<<cnt%mod<<endl; }
收集果子
#include<iostream> #include<cstdio> #include<cstring> #define maxn 1010 using namespace std; int w[maxn],ans,fa[maxn],sz[maxn],n,k; struct node{ int from,to; }E[maxn]; int find(int x){ if(x==fa[x])return x; return fa[x]=find(fa[x]); } void connect(int x,int y){ int f1=find(x),f2=find(y); if(f1==f2)return; fa[f2]=f1; sz[f1]+=sz[f2]; sz[f2]=0; } int main(){ freopen("fruit.in","r",stdin);freopen("fruit.out","w",stdout); // freopen("Cola.txt","r",stdin); scanf("%d%d",&n,&k); for(int i=1;i<=n;i++)scanf("%d",&w[i]); for(int i=1;i<n;i++)scanf("%d%d",&E[i].from,&E[i].to); int all=(1<<(n-1)); for(int i=0;i<all;i++){ for(int j=1;j<=n;j++)fa[j]=j,sz[j]=w[j]; int now=i,pos=0; while(now){ pos++; if(now&1){ connect(E[pos].from,E[pos].to); } now>>=1; } if(sz[find(1)]==k)ans++; } cout<<ans; return 0; }
/* 从根节点向下递归求方案数,回溯的时候将叶子儿子节点方案数累加到根节点上 */ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define mod 1000000007 #define maxn 1005 using namespace std; int n,k,a[maxn],num,head[maxn]; long long pw2[maxn],dp[maxn][maxn]; struct node{int to,pre;}e[maxn*2]; void Insert(int from,int to){ e[++num].to=to; e[num].pre=head[from]; head[from]=num; } int dfs(int now,int father){ int sz=1; for(int i=head[now];i;i=e[i].pre){ int to=e[i].to; if(to==father)continue; for(int j=0;j<=n-a[to];j++) dp[to][j+a[to]]=dp[now][j]; int tmp=dfs(to,now); for(int j=0;j<=n;j++) dp[now][j]=(pw2[tmp-1]*dp[now][j]%mod+dp[to][j])%mod; sz+=tmp; } return sz; } int main(){ freopen("fruit.in","r",stdin); scanf("%d%d",&n,&k); pw2[0]=1; for(int i=1;i<=n;i++)pw2[i]=pw2[i-1]*2%mod; for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=1,x,y;i<n;i++){ scanf("%d%d",&x,&y); Insert(x,y);Insert(x,y); } dp[1][a[1]]=1; dfs(1,0); cout<<dp[1][k]; return 0; }
预计得分100+30+20 实际得分100+60+30 T1一开始题意没懂,写完T2T3再看的,T1就是一个模拟,比较锻炼读题能力。T2看到位运算觉得有点蒙蔽,就直接暴力了,T3前30%的数据可以状态压缩搞一搞,写完发现最劣的情况是2^20*20,复杂度有可能过不去 今天状态不好,没集中精力做题,要培养善于调整的精神状态,积极投入考试