csps模拟测试7576一句话题解
题面:https://www.cnblogs.com/Juve/articles/11694454.html
75考了数学,化学和物理。。。
T1:
假设有一个A和B,那么对于每一个j!=i,都有$\frac{A}{a_i}+\frac{B}{b_i}<=\frac{A}{a_j}+\frac{B}{b_j}$
化一下式子,会卡出$\frac{A}{B}$的一个范围,判断范围是否有解即可
然后你n方了,75分
正解凸包?
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define int long long 6 #define re register 7 using namespace std; 8 const int MAXN=3e5+5; 9 int n,maxb,sta[MAXN],top=0; 10 bool vis[MAXN]; 11 struct node{ 12 int a,b,id; 13 friend bool operator < (node p,node q){ 14 return p.a==q.a?p.b>q.b:p.a>q.a; 15 } 16 }c[MAXN]; 17 inline double k(re node a,re node b){ 18 return (double)a.a*b.a*(b.b-a.b)/a.b/b.b/(b.a-a.a); 19 } 20 signed main(){ 21 //freopen("slay4.in","r",stdin); 22 scanf("%lld",&n); 23 for(re int i=1;i<=n;++i){ 24 scanf("%lld%lld",&c[i].a,&c[i].b); 25 c[i].id=i; 26 } 27 sort(c+1,c+n+1); 28 sta[++top]=1;maxb=c[1].b; 29 for(int i=2;i<=n;i++){ 30 if(c[i].b<=maxb) vis[i]=1; 31 else maxb=c[i].b; 32 } 33 for(int i=2;i<=n;i++){ 34 if(vis[i]) continue; 35 if(k(c[i],c[sta[top]])>0) continue; 36 while(top>1&&k(c[i],c[sta[top]])<k(c[sta[top-1]],c[sta[top]])) 37 --top; 38 sta[++top]=i; 39 } 40 memset(vis,0,sizeof(vis)); 41 for(int i=1;i<=top;i++){ 42 vis[c[sta[i]].id]=1; 43 for(int j=sta[i]+1;j<=n;++j){ 44 if(c[sta[i]].a!=c[j].a||c[sta[i]].b!=c[j].b) break; 45 vis[c[j].id]=1; 46 } 47 } 48 for(re int i=1;i<=n;++i){ 49 if(vis[i]) printf("%lld ",i); 50 } 51 puts(""); 52 return 0; 53 }
T2:
已知一些热化学方程式,求目标方程式的焓变
200个方程,每个方程中有200个反映物生成物
考高斯消元和字符串的处理
我们发现关键的物质前后都有空格,所以比较好读入
然后放到矩阵里消
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<string> 6 #include<map> 7 #include<cmath> 8 using namespace std; 9 const int MAXN=205; 10 const double eps=1e-8; 11 int n,m=0; 12 double a[MAXN][MAXN],val[MAXN]; 13 map<string,int>mp; 14 string in; 15 void gauss(){ 16 for(int i=1;i<=max(n,m);i++){ 17 int p=i; 18 for(int j=i+1;j<=n;j++) 19 if(fabs(a[j][i])>fabs(a[p][i])) p=j; 20 for(int j=1;j<=max(n,m)+1;j++) 21 swap(a[p][j],a[i][j]); 22 if(fabs(a[i][i])<eps) continue; 23 double tmp=a[i][i]; 24 for(int j=1;j<=max(n,m)+1;j++) 25 a[i][j]/=tmp; 26 for(int j=1;j<=n+1;j++) 27 if(i!=j){ 28 double tmp=a[j][i]; 29 for(int k=1;k<=max(n,m)+1;k++) 30 a[j][k]-=a[i][k]*tmp; 31 } 32 } 33 } 34 int main(){ 35 //freopen("knight1.in","r",stdin); 36 scanf("%d",&n); 37 for(int i=1;i<=n+1;++i){ 38 double xs; 39 while(in!="="){ 40 scanf("%lf",&xs); 41 cin>>in; 42 if(mp.find(in)==mp.end()) mp[in]=++m; 43 a[i][mp[in]]=xs; 44 cin>>in; 45 } 46 while(in!="H="){ 47 scanf("%lf",&xs); 48 cin>>in; 49 if(mp.find(in)==mp.end()) mp[in]=++m; 50 a[i][mp[in]]=-xs; 51 cin>>in; 52 } 53 if(i!=n+1) scanf("%lf",&val[i]); 54 } 55 for(int i=1;i<=n+1;++i){ 56 a[i][max(n,m)+1]=val[i]; 57 } 58 gauss(); 59 if(a[n+1][max(n,m)+1]==0) puts("0.0"); 60 else printf("%0.1lf\n",-a[n+1][max(n,m)+1]); 61 return 0; 62 }
T3:
不会,只有80分
第一问的话我们先按起点排序,然后根据终点求LIS,二分判断与k的大小关系
构造就GG了。。。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define int long long 7 using namespace std; 8 const int MAXN=1e5+5; 9 int n,k,ans=0,l=0,r=86400,res=0; 10 double b[MAXN],d[MAXN]; 11 struct node{ 12 int x,a,id; 13 double ed; 14 friend bool operator < (node p,node q){ 15 return p.x<q.x; 16 } 17 }od[MAXN]; 18 int c[MAXN]; 19 int lowbit(int x){ 20 return x&(-x); 21 } 22 void update(int pos,int val){ 23 while(pos<=n){ 24 c[pos]=max(c[pos],val); 25 pos+=lowbit(pos); 26 } 27 } 28 int query(int pos){ 29 int res=0; 30 while(pos>0){ 31 res=max(res,c[pos]); 32 pos-=lowbit(pos); 33 } 34 return res; 35 } 36 bool check(int tim){ 37 for(int i=1;i<=n;++i) d[i]=b[i]=(double)((double)(od[i].x)+(double)(0.5*(double)od[i].a*tim*tim)); 38 sort(d+1,d+n+1); 39 int cnt=unique(d+1,d+n+1)-d-1; 40 for(int i=1;i<=n;++i) b[i]=lower_bound(d+1,d+cnt+1,b[i])-d; 41 memset(c,0,sizeof(c)); 42 res=0; 43 for(int i=1;i<=n;++i){ 44 int tmp=query(b[i]-1)+1; 45 update(b[i],tmp); 46 res=max(res,tmp); 47 } 48 res=query(n); 49 return res>=k; 50 } 51 int fa[MAXN][21],dis[MAXN],minn[MAXN][21]; 52 int lca(int x,int y){ 53 int minnx=x,minny=y; 54 int i=0; 55 for(;(1<<i)<=dis[y];++i); 56 for(int j=i;j>=0;--j){ 57 if(fa[y][j]!=fa[x][j]){ 58 minnx=min(minnx,minn[x][j]); 59 minny=min(minny,minn[y][j]); 60 x=fa[x][j]; 61 y=fa[y][j]; 62 } 63 } 64 return minnx<minny; 65 } 66 pair<int,int>tr[MAXN]; 67 pair<int,int>max(pair<int,int> a,pair<int,int> b){ 68 if(a.first==b.first){ 69 return lca(a.second,b.second)?a:b; 70 } 71 else return a.first<b.first?b:a; 72 } 73 void add(int pos,pair<int,int>val){ 74 while(pos<=n){ 75 tr[pos]=max(tr[pos],val); 76 pos+=lowbit(pos); 77 } 78 } 79 pair<int,int>ask(int pos){ 80 pair<int,int>res=make_pair(0,0); 81 while(pos>0){ 82 res=max(res,tr[pos]); 83 pos-=lowbit(pos); 84 } 85 return res; 86 } 87 void prework(int tim){ 88 memset(minn,0x3f,sizeof(minn)); 89 for(int i=1;i<=n;++i) d[i]=b[i]=(double)((double)(od[i].x)+(double)(0.5*(double)od[i].a*tim*tim)); 90 sort(d+1,d+n+1); 91 int cnt=unique(d+1,d+n+1)-d-1; 92 for(int i=1;i<=n;++i) b[i]=lower_bound(d+1,d+cnt+1,b[i])-d; 93 for(int i=1;i<=n;++i){ 94 pair<int,int>tmp=ask(b[i]-1); 95 fa[od[i].id][0]=minn[od[i].id][0]=tmp.second; 96 dis[od[i].id]=dis[tmp.second]+1; 97 for(int j=1;j<=16;++j){ 98 fa[od[i].id][j]=fa[fa[od[i].id][j-1]][j-1]; 99 minn[od[i].id][j]=min(minn[od[i].id][j-1],minn[minn[od[i].id][j-1]][j-1]); 100 } 101 ++tmp.first; 102 tmp.second=od[i].id; 103 add(b[i],tmp); 104 } 105 } 106 int sta[MAXN],top=0; 107 signed main(){ 108 scanf("%lld%lld",&n,&k); 109 for(int i=1;i<=n;++i){ 110 scanf("%lld%lld",&od[i].x,&od[i].a); 111 od[i].id=i; 112 } 113 sort(od+1,od+n+1); 114 while(l<r){ 115 int mid=(l+r)>>1; 116 if(check(mid)) ans=mid,l=mid+1; 117 else r=mid; 118 } 119 printf("%lld\n",ans); 120 check(ans); 121 if(res>k){ 122 puts("-1"); 123 return 0; 124 }else{ 125 prework(ans); 126 int x=ask(n).second; 127 sta[++top]=x; 128 while(fa[x][0]){ 129 x=fa[x][0]; 130 sta[++top]=x; 131 } 132 sort(sta+1,sta+top+1); 133 for(int i=1;i<=top;++i){ 134 printf("%lld\n",sta[i]); 135 } 136 } 137 return 0; 138 }
76:
集训过了1/3了,我还如此的菜。。。。。。
T1构造题,注意动态维护块长
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int MAXN=1e5+5; 7 int T,n,a,b; 8 void work(){ 9 int p=n-a+1; 10 for(int i=p;i<=n;++i){ 11 printf("%d ",i); 12 } 13 int tot=n-a; 14 if(!tot){ 15 puts(""); 16 return ; 17 } 18 int siz=(tot-1)/(b-1); 19 for(int i=1;i<b;++i){ 20 if(!tot) break; 21 siz=(tot)/(b-i); 22 for(int j=1;j<=siz;++j){ 23 printf("%d ",tot-siz+j); 24 } 25 tot-=siz; 26 } 27 if(tot) printf("1"); 28 puts(""); 29 } 30 int main(){ 31 scanf("%d",&T); 32 while(T--){ 33 bool flag=0; 34 scanf("%d%d%d",&n,&a,&b); 35 if(a>n||b>n||a<1||b<1||a*b<n||n-a<b-1){ 36 puts("No"); 37 continue; 38 } 39 puts("Yes"); 40 work(); 41 } 42 return 0; 43 }
T2:
排序求前缀和,如果$\frac{a_i}{2}>sum_{i-1}$,那么会有断点,求断点长度即可
注意向上取整
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define int long long 6 using namespace std; 7 const int MAXN=1e5+5; 8 int n,a[MAXN],ans=0,sum[MAXN]; 9 signed main(){ 10 scanf("%lld",&n); 11 for(int i=1;i<=n;++i) scanf("%lld",&a[i]); 12 sort(a+1,a+n+1); 13 for(int i=1;i<=n;++i) sum[i]=sum[i-1]+a[i]; 14 for(int i=1;i<=n;++i){ 15 if((a[i]+1)/2>sum[i-1]) 16 ans+=(a[i]+1)/2-sum[i-1]-1; 17 } 18 printf("%lld\n",sum[n]-ans); 19 return 0; 20 }
T3:
dp记忆化搜索
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define int long long 6 using namespace std; 7 const int MAXN=405; 8 const int mod=1e9+7; 9 int t,n,ans=0,m,liml[MAXN],limr[MAXN],dp[MAXN][MAXN]; 10 void preinit(){ 11 memset(dp,-1,sizeof(dp)); 12 for(int i=1;i<=n;++i) liml[i]=0,limr[i]=n-i+1,dp[i][0]=1; 13 dp[n+1][0]=1; 14 for(int i=1,x,y;i<=m;++i){ 15 scanf("%lld%lld",&x,&y); 16 if(x<y) limr[x]=min(limr[x],y-x-1); 17 else liml[y]=max(liml[y],x-y); 18 } 19 } 20 int dfs(int now,int siz){ 21 if(dp[now][siz]!=-1) return dp[now][siz]; 22 ++dp[now][siz]; 23 for(int k=liml[now];k<=min(siz,limr[now]);++k){ 24 dp[now][siz]=(dp[now][siz]+dfs(now+1,k)*dfs(now+1+k,siz-1-k)%mod)%mod; 25 } 26 return dp[now][siz]; 27 } 28 signed main(){ 29 //freopen("sample.in","r",stdin); 30 scanf("%lld",&t); 31 while(t--){ 32 scanf("%lld%lld",&n,&m); 33 preinit(); 34 printf("%lld\n",dfs(1,n)); 35 } 36 return 0; 37 }