2019 Multi-University Training Contest 2
Posted mountaink
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2019 Multi-University Training Contest 2相关的知识,希望对你有一定的参考价值。
题号 | A | B | C | D | E | F | G | H | I | J | K | L |
状态 | . |
. |
. | . | Ο | . | . | . | . | Ο | Ο | Ο |
1005 Everything Is Generated In Equal Probability
//#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<string> #include<math.h> #include<cmath> #include<time.h> #include<map> #include<set> #include<vector> #include<queue> #include<algorithm> #include<numeric> #include<stack> #include<bitset> #include<unordered_map> const int maxn = 0x3f3f3f3f; const double EI = 2.71828182845904523536028747135266249775724709369995957496696762772407663035354594571382178525166427; const double PI = 3.141592653589793238462643383279; //#ifdef TRUETRUE //#define gets gets_s //#endif using namespace std; long long p = 998244353; long long quick(long long a, int b, int c) long long ans = 1; a = a % c; while (b != 0) if (b & 1) ans = (ans * a) % c; b >>= 1; a = (a * a) % c; return ans; struct s long long a, b,ans; z[3010]; long long ans[3010], aa[3010]; int main(void) int i, j, k; long long zz = 2; z[1].a = 0; z[1].ans = 0; long long z3 = quick(3, p - 2, p); //printf(" %lld\n",z3); for (i = 2; i <= 3000; i++) z[i].a = z[i - 1].a + zz; z[i].a %= p; z[i].ans = (z[i].a * z3) % p; zz += 2; zz %= p; ans[1] = 0; aa[1] = 0; for (i = 2; i <= 3000; i++) ans[i] = (ans[i - 1] + z[i].ans) % p; aa[i] = (ans[i] * quick(i, p - 2, p)) % p; int N; while (~scanf("%d", &N)) printf("%lld\n", aa[N]); return 0;
//#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<string> #include<math.h> #include<cmath> #include<time.h> #include<map> #include<set> #include<vector> #include<queue> #include<algorithm> #include<numeric> #include<stack> #include<bitset> #include<unordered_map> const int maxn = 0x3f3f3f3f; const double EI = 2.71828182845904523536028747135266249775724709369995957496696762772407663035354594571382178525166427; const double PI = 3.141592653589793238462643383279; //#ifdef TRUETRUE //#define gets gets_s //#endif using namespace std; long long p = 1e6 + 3; int main(void) long long n,i,ans; while (~scanf("%lld",&n)) if (n >= p) printf("0\n"); continue; ans = 1; for (i = 1;i <= n;i++) ans *= i; ans %= p; printf("%lld\n",ans); return 0;
1011 Keen On Everything But Triangle
题意:给出n根火柴,q次询问,每次询问[l,r]区间内的火柴组成三角形的最长周长是多少。
思路:考虑暴力,必定是将l到r区间内的所有数字排序,然后从大到小依次check相邻的三根火柴能否组成三角形。
考虑优化,由斐波那契数列的性质可得,45根1e9范围内的火柴必定能组成一个三角形(最坏情况是1,1,2,3,5,第45项就超过1e9了),所以线段树区间维护46个最大值,然后做上面的check就可以了。
#include<bits/stdc++.h> #define clr(a,b) memset(a,b,sizeof(a)) using namespace std; typedef long long ll; const int maxn=200010; struct node int l,r,size; ll a[50]; tr[maxn<<2]; ll val[maxn]; int n,q; inline ll rd() ll x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘)if(ch==‘-‘)f=-1;ch=getchar(); while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘;ch=getchar(); return x*f; inline void pushup(int o,int oa,int ob) int i=1,j=1,k=0; while(++k<=tr[o].size) if(i<=tr[oa].size&&tr[oa].a[i]>=tr[ob].a[j]) tr[o].a[k]=tr[oa].a[i]; i++; else tr[o].a[k]=tr[ob].a[j]; j++; inline void build(int o,int l,int r) tr[o].size=min(r-l+1,46); for(int i=1;i<=tr[o].size;i++) tr[o].a[i]=0; if(l==r) tr[o].a[1]=val[l]; return; int mid=(l+r)>>1; build(o<<1,l,mid); build(o<<1|1,mid+1,r); pushup(o,o<<1,o<<1|1); ll ans[50],temp[50]; int top=0; inline void query(int o,int l,int r,int ql,int qr) if(ql<=l&&r<=qr) int si=min(46,top+tr[o].size); int i=1,j=1,k=0; while(++k<=si) if(i<=top&&ans[i]>=tr[o].a[j]) temp[k]=ans[i]; i++; else temp[k]=tr[o].a[j]; j++; top=si; for(int i=1;i<=top;i++) ans[i]=temp[i]; for(int i=top+1;i<=46;i++) ans[i]=0; return; int mid=(l+r)>>1; if(ql<=mid)query(o<<1,l,mid,ql,qr); if(mid<qr)query(o<<1|1,mid+1,r,ql,qr); int main() while(cin>>n>>q) for(int i=1;i<=n;i++) // scanf("%lld",&val[i]); val[i]=rd(); build(1,1,n); while(q--) int l,r; top=0; l=rd(),r=rd(); query(1,1,n,l,r); ll an=-1; for(int i=1;i<=top-2;i++) if(ans[i]<ans[i+1]+ans[i+2]) an=ans[i]+ans[i+1]+ans[i+2]; break; printf("%lld\n",an);
1012 Longest Subarray
题意:给出n个数字,求一个最长子串,要求这个串包含的数字的次数必定大于等于k。
思路:先将整体的字符串,次数小于k的数全部去掉,得到若干个不连续的子串,对这些子串递归做这个工作。调一下参数,递归到30层时直接return。
(这个做法可以被hack,但数据比较难造,赌出题人没有卡这个做法,队友tql)
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) #define dep(i,a,b) for(int i=b;i>=a;i--) using namespace std; #define ll long long const int N=3e5+5; const int mod = 998244353; int a[301010],c[301010],q[301010]; int n,C,k,ans; ll rd() ll x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘)if(ch==‘-‘)f=-1;ch=getchar(); while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘;ch=getchar(); return x*f; void solve(int l,int r,int dep) if(dep>=30) return; //printf("l=%d r=%d\n",l,r); if(r-l+1<=ans) return; int flag=0,pre,cnt=0; rep(i,l,r) c[a[i]]=0; rep(i,l,r) ++c[a[i]]; q[++cnt]=l-1; rep(i,l,r) if(c[a[i]]<k) q[++cnt]=i; flag=1; q[++cnt]=r+1; if(flag==0) ans=r-l+1; rep(i,1,cnt) solve(q[i]+1,q[i+1]-1,dep+1); int main() // freopen("1.in","r",stdin); // freopen("1.out","w",stdout); while(~scanf("%d%d%d",&n,&c,&k)) ans=0; rep(i,1,n) a[i]=rd(); solve(1,n,1); printf("%d\n",ans);
以上是关于2019 Multi-University Training Contest 2的主要内容,如果未能解决你的问题,请参考以下文章
2019 Multi-University Training Contest 6
2019 Multi-University Training Contest 6
2019 Multi-University Training Contest 6
2019 Multi-University Training Contest 3