2021.9.15

T1:滞空

Problem:

pyy在平面上第一象限内发现了顺序n个平台(她可以踩在这些平台上,但必须从第i-1号平台跳跃至i号平台),这些平台的横坐标互异且单调递增,从1号平台出发依次跳跃经过2->n号平台不允许落地。给出pyy的质量m和重力加速度g(重力沿y轴负方向),考虑理想情况下,求pyy需要消耗的最小能量(不考虑落至平台冲量(即落至平台后速度为0
))(单位J)。
可能用到的公式定理:
1·能量守恒(理想情况下转换效率100%)
2·动能定理(E=0.5*m*v2)
3·牛顿第二定律(匀加速运动下速度从0开始,x=0.5*a*t2)
4·重力势能公式(E=m*g*h)
5·匀速运动的距离公式(x=v*t)
设E为能量,m为质量,v为速度,x为位移,a为加速度,t为时间,h为两个点高度差。
能量守恒指在本题中初始动能视为人体能量消耗;
牛顿第二定律给出加速运动中,加速度与位移间关系的公式;
动能定理和重力势能公式给出能量计算公式。

Solution:

纯物理题...

Code:

 1 #include<bits/stdc++.h>
 2 #define int long long
 3 using namespace std;
 4 const int mod=998244353;
 5 const int N=1e6+5;
 6 int n,m,g,x[N],y[N];
 7 int ans,G,s;
 8 inline int read(){
 9     int x=0,f=1;
10     char ch=getchar();
11     while(ch<'0'||ch>'9'){
12         if(ch=='-') f=-1;
13         ch=getchar();
14     }
15     while(ch>='0'&&ch<='9'){
16         x=(x<<1)+(x<<3)+(ch^48);
17         ch=getchar();
18     }
19     return x*f;
20 }
21 inline int Pow(int x,int y){
22     int res=1;
23     for(;y;y>>=1,x=x*x%mod){
24         if(y&1){
25             res=res*x%mod;
26         }
27     }
28     return res;
29 }
30 inline int Abs(int x){
31     return x>0?x:-x;
32 }
33 signed main(){
34     s=Pow(2,mod-2)%mod;
35     n=read();
36     m=read();
37     g=read();
38     G=m*g%mod;
39     for(int i=1;i<=n;i++){
40         x[i]=read();
41         y[i]=read();
42     }
43     for(int i=1;i<n;i++){
44         int h=Abs(y[i+1]-y[i])%mod;
45         int l=Abs(x[i+1]-x[i])%mod;
46         if(y[i+1]>y[i]){
47             ans=(ans+(G*h%mod+(((G*l)%mod*l)%mod*(Pow(4*h%mod,mod-2)%mod)))%mod)%mod;
48         }
49         if(y[i+1]<y[i]){
50             ans=(ans+(((G*l)%mod*l)%mod*(Pow(4*h%mod,mod-2)%mod))%mod)%mod;
51         }
52         if(y[i+1]==y[i]){
53             ans=(ans+(s*G)%mod*l%mod)%mod;
54         }
55     }
56     printf("%lldJ\n",ans);
57     return 0;
58 }

T2:放爆竹

Problem:

小辉将很多地雷和春雷穿成了n串。因为地雷和春雷爆炸的声音是不一样的,所以串起来以后,爆炸的声音也是不一样的。
小辉原本想让小明告诉他,如果同时点燃n串雷,最多会有多长的时间至少有两串雷爆炸的声音是一样的。
但是小辉觉得这个问题真是太简单了,所以决定问小明,如果在山谷中(有回音)同时点燃n串雷,那最多会有多长的时间至少有两串雷爆炸的声音是一样的呢?
小辉认为一枚春雷或者地雷爆炸都需要1ms,且山谷中的回音不减弱,并且小辉给出的雷串不会是任意一个雷串的重复(不管重复的雷串是否存在,即无论如何都不会存在类似于01010101的雷串)。

Solution:

找循环字符串的最长公共前缀(注意从开头开始比较)

Code:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=1e7;
 4 const int lim=550;
 5 int n,cnt,t[N][2];
 6 char s[505];
 7 int ans,p[N],l[N];
 8 inline void insert(string s){
 9     int now=0,nowl=0;
10     while(1){
11         if(nowl>lim) break;
12         for(int i=0;s[i]&&nowl<=lim;i++){
13             if(!t[now][s[i]-'0']){
14                 t[now][s[i]-'0']=++cnt;
15                 l[t[now][s[i]-'0']]=l[now]+1; 
16             }
17             now=t[now][s[i]-'0'];
18             p[now]++;
19             nowl++;
20         }
21     }
22 }
23 int main(){
24     scanf("%d",&n);
25     for(int i=1;i<=n;i++){
26         scanf("%s",s);
27         insert(s);
28     }
29     for(int i=1;i<=cnt;i++){
30         if(p[i]>=2){
31             ans=max(ans,l[i]);
32         }
33     }
34     cout<<ans<<endl;
35     return 0;
36 }

T3:pyy整队

Problem:

众所周知pyy当了班长,服务于民。一天体育课,趁体育老师还没来,pyy让班里n个同学先排好队。老师不在,同学们开始玩起了手机。站在队伍前端玩手机,前面的人少了,谁都顶不住。于是陆陆续续有人往队伍最后躲去,但大家都沉迷某骗氪手游,忘记了老师说前面位置有空缺要补齐的要求。一些同学还时不时地低头问向指挥队伍的班长pyy,排在自己前面成绩最好的同学是谁,这样自己才能心安理得放心大胆的继续玩手机。
这时老师来了,同学们在可以忽略不计的时间内收好了手机。看着到处充满空缺的队伍,体育老师勃然大怒并借题发挥,以扬体育组声威,限pyy以最快的时间整顿队伍。由于是体育老师,并看不出来队伍的位置后移了,老师只关心队伍是否整齐没有空缺。
老师给了pyy一次移动一名同学的权力,因此pyy无法使用技能“向前看齐”。pyy的哥哥强制要求你帮助pyy回答之前同学们的问题,并告诉pyy在老师来之后,至少移动多少个同学可以使队伍整齐。
若为A,x,则表示年级成绩排名为x的同学向pyy询问自己前面成绩最好的是哪位同学;若为M,x,则表示年级成绩排名为x的同学此时躲到了当前队伍的最尾端(不存在队尾同学躲向队尾)。

Solution:

动态开点线段树

Code:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=200010;
 4 int a[N],b[N],nxt[N],pre[N],id[N];
 5 int cnt,rt,tot;
 6 struct node{
 7     int mi,ls,rs;
 8 }t[3200010];
 9 inline void pushup(int x){
10     t[x].mi=min(t[t[x].ls].mi,t[t[x].rs].mi);
11 }
12 inline void build(int &x,int l,int r){
13     if(!x) x=++cnt;
14     if(l==r){
15         t[x].mi=id[l];
16         return ;
17     }
18     int mid=(l+r)>>1;
19     build(t[x].ls,l,mid);
20     build(t[x].rs,mid+1,r);
21     pushup(x);
22 }
23 inline int que(int x,int l,int r,int val){
24     while(l<r){
25         int mid=(l+r)>>1;
26         if(t[t[x].ls].mi<=val){
27             x=t[x].ls;
28             r=mid;
29         }
30         else{
31             x=t[x].rs;
32             l=mid+1;
33         }
34     }
35     return l;
36 }
37 inline void mov(int x,int l,int r,int val){
38     if(l==r){
39         t[x].mi=++tot;
40         return ;
41     }
42     int mid=(l+r)>>1;
43     if(val<=mid) mov(t[x].ls,l,mid,val);
44     else mov(t[x].rs,mid+1,r,val);
45     pushup(x);
46 }
47 int main(){
48     int n,m;
49     scanf("%d%d",&n,&m);
50     for(int i=1;i<=n;i++){
51         scanf("%d",a+i);
52         b[i]=a[i];
53     }
54     sort(b+1,b+n+1);
55     for(int i=1;i<=n;i++){
56         a[i]=lower_bound(b+1,b+n+1,a[i])-b;
57         nxt[a[i-1]]=a[i];
58         pre[a[i]]=a[i-1];
59         id[a[i]]=i;
60     }
61     build(rt,1,n);
62     tot=n;
63     int ta=a[n];
64     for(int i=1;i<=m;i++){
65         char opt;
66         int x;
67         cin>>opt;
68         scanf("%d",&x);
69         int now=lower_bound(b+1,b+n+1,x)-b;
70         if(opt=='A'){
71             if(!pre[now]) cout<<"-1"<<endl;
72             else cout<<b[que(rt,1,n,id[pre[now]])]<<endl;
73         }
74         else{
75             if(now==ta) continue;
76             mov(rt,1,n,now);
77             id[now]=tot;
78             nxt[pre[now]]=nxt[now];
79             pre[nxt[now]]=pre[now];
80             pre[now]=ta;
81             nxt[ta]=now;
82             ta=now;
83         }
84     }
85     sort(id+1,id+n+1);
86     int la=0,ans=100010;
87     for(int i=1;i<=n&&la<n;i++){
88         while(id[la+1]-id[i]+1<=n&&la<n) la++;
89         ans=min(ans,i-1+n-la);
90     } 
91     cout<<ans<<endl;
92     return 0;
93 }
posted @ 2021-09-15 19:53  B_lank  阅读(49)  评论(0)    收藏  举报