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