10.20 模拟赛

T2模的不够多AK失败 被熊神和低年级爆踩的一次模拟赛

T1 timezone

题目大意:

一趟飞机的起降时间皆为当地时间(考虑时差)

现在已知A-B的航班的起降时间与B-A的航班的起降时间

求这个航班的真实飞行时间 

思路:

设时间分别为a b c d

可以想到把b和c重合 然后用d-a/2 随便搞一下即可

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 #include<map>
10 #define inf 2139062143
11 #define ll long long
12 #define MAXN 100100
13 using namespace std;
14 inline int read()
15 {
16     int x=0,f=1;char ch=getchar();
17     while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
19     return x*f;
20 }
21 char ch[50];
22 int n;
23 struct Time
24 {
25     int h,m,s;
26     Time(){h=m=s=0;}
27     void init()
28     {
29         n=strlen(ch+1);
30         h=(ch[1]-'0')*10+ch[2]-'0',m=(ch[4]-'0')*10+ch[5]-'0',s=(ch[7]-'0')*10+ch[8]-'0';
31         scanf("%s",ch+1);if(ch[1]=='(') {h+=24*(ch[3]-'0');scanf("%s",ch+1);}
32     }
33     void print()
34     {
35         printf("%02d:%02d:%02d\n",h,m,s);
36     }
37     void div2()
38     {
39         if(h&1) m+=60;h>>=1;
40         if(m&1) s+=60;m>>=1;s>>=1;
41     }
42 }a,b,c,d,e,f;
43 Time operator + (const Time x,const Time y)
44 {
45     Time res;
46     res.s=x.s+y.s,res.m=res.s/60,res.s%=60;
47     res.m+=x.m+y.m,res.h=res.m/60,res.m%=60;
48     res.h+=x.h+y.h;
49     return res;
50 }
51 Time operator - (const Time x,const Time y)
52 {
53     Time res;
54     res.s=x.s-y.s;if(res.s<0) res.s+=60,res.m=-1;
55     res.m+=x.m-y.m;if(res.m<0) res.m+=60,res.h=-1;
56     res.h+=x.h-y.h;
57     return res;
58 }
59 int main()
60 {
61     freopen("timezone.in","r",stdin);
62     freopen("timezone.out","w",stdout);
63     int T=read();scanf("%s",ch+1);
64     while(T--)
65     {
66         a.init();b.init();c.init();d.init();
67         //a.print();b.print();c.print();d.print();
68         a=b-a;c=d-c;
69         //c.print();b.print();e.print();
70         d=c+a;d.div2();d.print();//puts("");
71     }
72 }
View Code

 

T2 sumsum

题目大意:

一个数列 支持两种操作

1区间加 2查询区间二阶和(即s i 的和)

思路:

线段树维护一阶前缀和 修改的时候对答案的贡献是一个一次函数 维护两个tag即可

查询的时候用区间和减去区间左端点的值*区间长度即可

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 #include<map>
10 #define inf 2139062143
11 #define ll long long
12 #define MAXN 501000
13 #define MOD 1000000007
14 using namespace std;
15 inline int read()
16 {
17     int x=0,f=1;char ch=getchar();
18     while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
19     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
20     return x*f;
21 }
22 int n,m;
23 ll val[MAXN<<2],sum[MAXN<<2],tags[MAXN<<2],tagd[MAXN<<2];
24 void build(int k,int l,int r)
25 {
26     if(l==r) {sum[k]=val[l],tags[k]=tagd[k]=0;return ;}
27     int mid=l+r>>1;
28     build(k<<1,l,mid);build(k<<1|1,mid+1,r);
29     sum[k]=sum[k<<1]+sum[k<<1|1];
30 }
31 inline void pshd(int k,int l,int r,int mid)
32 {
33     (sum[k<<1]+=(tags[k]*((ll)mid-l+1))%MOD+(tagd[k]*((((ll)mid-l+1)*((ll)mid-l+2)/2)%MOD))%MOD)%=MOD;
34     (sum[k<<1|1]+=((tags[k]+(((ll)mid-l+1)*tagd[k])%MOD)*((ll)r-mid))%MOD+(tagd[k]*((((ll)r-mid)*((ll)r-mid+1)/2)%MOD))%MOD)%=MOD;
35     (tags[k<<1]+=tags[k])%=MOD,(tags[k<<1|1]+=tags[k]+((ll)mid-l+1)*tagd[k])%=MOD,tags[k]=0;
36     (tagd[k<<1]+=tagd[k])%=MOD,(tagd[k<<1|1]+=tagd[k])%=MOD,tagd[k]=0;
37 }
38 void mdf(int k,int l,int r,int a,int b,ll s,ll x)
39 {
40     //cout<<"M: "<<k<<" "<<l<<" "<<r<<" "<<a<<" "<<b<<" "<<s<<" "<<x<<endl;
41     if(l==a&&r==b) {(sum[k]+=(s*((ll)b-a+1)%MOD)+(x*((((ll)b-a+1)*((ll)b-a+2)/2)%MOD))%MOD)%=MOD,(tags[k]+=s)%=MOD,(tagd[k]+=x)%=MOD;return ;}
42     int mid=l+r>>1;pshd(k,l,r,mid);
43     if(b<=mid) mdf(k<<1,l,mid,a,b,s,x);
44     else if(a>mid) mdf(k<<1|1,mid+1,r,a,b,s,x);
45     else {mdf(k<<1,l,mid,a,mid,s,x);mdf(k<<1|1,mid+1,r,mid+1,b,(s+((ll)mid-a+1)*x)%MOD,x);}
46     sum[k]=(sum[k<<1]+sum[k<<1|1])%MOD;
47 }
48 ll query(int k,int l,int r,int a,int b)
49 {
50     //cout<<"Q: "<<k<<" "<<l<<" "<<r<<" "<<a<<" "<<b<<" "<<sum[k]<<" "<<tags[k]<<" "<<tagd[k]<<endl;
51     if(l==a&&r==b) return sum[k];
52     int mid=l+r>>1;pshd(k,l,r,mid);
53     if(b<=mid) return query(k<<1,l,mid,a,b);
54     else if(a>mid) return query(k<<1|1,mid+1,r,a,b);
55     else return (query(k<<1,l,mid,a,mid)+query(k<<1|1,mid+1,r,mid+1,b))%MOD;
56 }
57 int main()
58 {
59     freopen("sumsum.in","r",stdin);
60     freopen("sumsum.out","w",stdout);
61     n=read(),m=read();ll a,b,c;
62     for(register int i=1;i<=n;i++) val[i]=(val[i-1]+read())%MOD;
63     build(1,1,n);
64     while(m--)
65     {
66         c=read();
67         if(c&1) {a=read(),b=read(),c=read();mdf(1,1,n,a,b,0,c);if(b<n) mdf(1,1,n,b+1,n,(c*((ll)b-a+1))%MOD,0);}
68         else {a=read(),b=read();c=query(1,1,n,a,b);if(a>1) c-=(query(1,1,n,a-1,a-1)*((ll)b-a+1))%MOD;printf("%lld\n",(c%MOD+MOD)%MOD);}
69     }
70 }
View Code

 

T3 merge

题目大意:

把一个数列合并为一个数 代价为两个数差的绝对值 合并后数为最右边数的权值

求最小代价

思路:

区间dp

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 #include<map>
10 #define inf 2139062143
11 #define ll long long
12 #define MAXN 210
13 using namespace std;
14 inline int read()
15 {
16     int x=0,f=1;char ch=getchar();
17     while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
19     return x*f;
20 }
21 int n,dp[MAXN][MAXN],a[MAXN],b[MAXN],ans=inf;
22 int main()
23 {
24     freopen("merge.in","r",stdin);
25     freopen("merge.out","w",stdout);
26     n=read();memset(dp,127,sizeof(dp));
27     for(int i=1;i<=n;i++) a[i]=a[n+i]=read(),b[i]=b[n+i]=read(),dp[i][i]=dp[n+i][n+i]=0;
28     for(int j=1;j<=2*n;j++)
29         for(int i=1;i+j<=2*n;i++)
30             for(int k=i;k<i+j;k++) 
31                 dp[i][i+j]=min(dp[i][i+j],dp[i][k]+dp[k+1][i+j]+abs(b[i+j]-b[k]));
32     for(int i=1;i<=n;i++) ans=min(ans,dp[i][i+n-1]);
33     printf("%d",ans);
34 }
View Code

 

posted @ 2018-10-20 18:08  jack_yyc  阅读(152)  评论(0编辑  收藏  举报