10.11NOIP模拟题(2)
/* string水过 */ #include<bits/stdc++.h> #define N 1001 using namespace std; int n,x,y,m,pre; string str; string s[N]; inline int read() { int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } int main() { freopen("y.in","r",stdin); freopen("y.out","w",stdout); n=read(); for(register int i=1;i<=n;i++) cin>>s[i]; str="I_love_"; m=read(); for(register int i=1;i<=m;i++) { x=read();y=read(); s[x]=str;s[x]+=s[y];pre=x; } cout<<s[1]; return 0; }
/* ai<=ai+1时 枚举每一个区间长度二分右端点 */ #include<bits/stdc++.h> #define N 500001 #define ll long long using namespace std; ll n,ans,K,m; ll a[N],sum[N]; inline ll read() { int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } void work1() { while(m--) { K=read();ans=0; for(int j=1;j<=n;j++) { for(int k=j;k<=n;k++) { ll res1=sum[k]-sum[j-1]; ll res2=k-j+1; if(res1<=K*res2) ans++; } } cout<<ans<<endl; } } void work2() { ll l,r,mid,tmp,lim; while(m--) { K=read();ans=0;lim=1;tmp=0; for(int L=1;L<=n;L++) { l=1;r=n+1;lim=L*K; while(l<=r) { mid=(l+r)>>1; if(sum[mid]-sum[mid-L]<=lim && sum[mid]) tmp=mid,l=mid+1; else r=mid-1; } if(tmp-L+1>0) ans+=tmp-L+1; } cout<<ans<<endl; } } int main() { freopen("h.in","r",stdin); freopen("h.out","w",stdout); n=read(); for(int i=1;i<=n;i++) a[i]=read(); for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i]; m=read(); if(n<=100) work1(); else work2(); return 0; }
/* 将数列减k转化为求区间和<=0的区间个数 前缀和,求多少l,r满足s[r]-s[l-1]<=0 即s[r]<=s[L](L=l-1) 树状数组求逆序对 */ #include<bits\stdc++.h> #define N 50001 #define ll long long using namespace std; ll n,m,k; ll ori[N],a[N],b[N],tmp[N]; inline int discrete() { for(int i=1;i<=n;i++) tmp[i]=a[i]; sort(tmp+1,tmp+n+1); ll *end=unique(tmp+1,tmp+n+1); for(int i=1;i<=n;i++) a[i]=lower_bound(tmp+1,end,a[i])-tmp; return end-(tmp+1); } struct BinaryIndexedTree { int n; ll a[N]; static int lowbit(int x) { return x & -x; } void clear() { for(int i=1;i<=n;i++) a[i]=0; } ll query(int pos) { ll ans=0; for(int i=pos;i>0;i-=lowbit(i)) ans+=a[i]; return ans; } void update(int pos,int del) { for(int i=pos;i<=n;i+=lowbit(i)) a[i]+=del; } }bit; inline ll read() { ll x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } inline ll solve(int k) { ll ans=0; for(int i=1;i<=n;i++) { a[i]=ori[i]-k+a[i-1]; if(a[i]<=0) ans++; } bit.n=discrete(); bit.clear(); for(int i=n;i>=1;i--) { ans+=bit.query(a[i]); bit.update(a[i],1); } return ans; } int main() { freopen("h.in","r",stdin); freopen("h.out","w",stdout); n=read(); for(int i=1;i<=n;i++) ori[i]=read(); m=read(); while(m--) { k=read(); printf("%lld\n",solve(k)); } }
#include<iostream> #include<cstdio> #include<cstring> #define N 3001 using namespace std; int n,m,T,flag; char ch; bool e1[N][N],e2[N][N]; void floyed() { flag=0; for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) if(i!=j && j!=k) { if(e1[i][k] && e1[k][j] && !e1[i][j]) flag=1; if(flag) break; if(e2[i][k] && e2[k][j] && !e2[i][j]) flag=1; if(flag) break; } if(flag) break; } } int main() { freopen("p.in","r",stdin); freopen("p.out","w",stdout); scanf("%d",&T); while(T--) { scanf("%d",&n); memset(e1,0,sizeof e1); memset(e2,0,sizeof e2); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { cin>>ch; if(ch=='H') e1[i][j]=1; if(ch=='W') e2[i][j]=1; } floyed(); if(flag) printf("N0\n"); else printf("YE5\n"); } return 0; }
/* 考虑u->v和v->w都被一个人占领 那么答案为N0的情况为 1.w->u 另一人占领 2.u->w 另一人占领 3.w->u 同一人占领 1,3有环 2 将一个人反向建图有环 所以两次拓扑排序判断是否有换即可 */ #include<bits\stdc++.h> #define N 3001 using namespace std; int n,m,k,ans,flag; char s[N][N]; int e[N][N],in[N]; void T_sort() { memset(in,0,sizeof in); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(e[i][j]) in[j]++; for(int i=1;i<=n;i++) { int u=0; for(int j=1;j<=n;j++) { if(in[j]==0) { u=j;in[j]=-1;break; } } if(!u){flag=1;return;} for(int j=1;j<=n;j++) if(e[u][j]) in[j]--; } } int main() { freopen("p.in","r",stdin); freopen("p.out","w",stdout); int T; scanf("%d",&T); while(T--) { scanf("%d",&n); flag=0; for(int i=1;i<=n;i++) scanf("%s",s[i]+1); for(int k=0;k<=1;k++) { memset(e,0,sizeof e); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(s[i][j]=='H') e[i][j]=1; if(s[i][j]=='W') { if(!k) e[i][j]=1; else e[j][i]=1; } } T_sort(); } if(!flag) printf("YE5\n"); else printf("N0\n"); } }
折花枝,恨花枝,准拟花开人共卮,开时人去时。
怕相思,已相思,轮到相思没处辞,眉间露一丝。