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 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code

 

posted @ 2019-10-17 20:22  xukl21  阅读(194)  评论(0编辑  收藏  举报