2019 Multi-University Training Contest 2

http://acm.hdu.edu.cn/contests/contest_show.php?cid=849

1005. Everything Is Generated In Equal Probability

考虑一个随机的排列的逆序对个数,显然对于两个数\(a,b\),他们位置是均匀排布的,也就是说有\(\frac{1}{2}\)的概率成为逆序对,并且是独立的。

所以一个长度为\(n\)的随机排列期望逆序对个数为\(\dfrac{\binom{n}{2}}{2}\)。

我们考虑\(dp\),设\(f_i\)表示长度为\(i\)随机排列扔到给出的函数里的期望输出。

那么直接照着函数转移:

\[f_i=\frac{\binom{n}{2}}{2}+\frac{1}{2^n}\sum_{j=0}^{i}\binom{i}{j}f_j
\]

暴力转移,\(O(1)\)回答就好了。

复杂度\(O(n^2+q)\)。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. void read(int &x) {
  4. x=0;int f=1;char ch=getchar();
  5. for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
  6. for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
  7. }
  8. void print(int x) {
  9. if(x<0) putchar('-'),x=-x;
  10. if(!x) return ;print(x/10),putchar(x%10+48);
  11. }
  12. void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}
  13. #define lf double
  14. #define pii pair<int,int >
  15. #define vec vector<int >
  16. #define pb push_back
  17. #define mp make_pair
  18. #define fr first
  19. #define sc second
  20. #define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++)
  21. const int maxn = 1e6+10;
  22. const int inf = 1e9;
  23. const lf eps = 1e-8;
  24. const int mod = 998244353;
  25. int f[maxn],fac[maxn],ifac[maxn],n;
  26. int qpow(int a,int x) {
  27. int res=1;
  28. for(;x;x>>=1,a=1ll*a*a%mod) if(x&1) res=1ll*res*a%mod;
  29. return res;
  30. }
  31. int c(int a,int b) {return 1ll*fac[a]*ifac[b]%mod*ifac[a-b]%mod;}
  32. int main() {
  33. fac[0]=ifac[0]=1;
  34. for(int i=1;i<=3000;i++) fac[i]=1ll*fac[i-1]*i%mod,ifac[i]=1ll*ifac[i-1]*qpow(i,mod-2)%mod;
  35. for(int i=2;i<=3000;i++) {
  36. for(int j=2;j<=i-1;j++) f[i]=(f[i]+1ll*f[j]*c(i,j)%mod)%mod;
  37. f[i]=1ll*f[i]*qpow(qpow(2,i),mod-2)%mod;
  38. f[i]=(f[i]+1ll*c(i,2)*qpow(2,mod-2)%mod)%mod;
  39. f[i]=1ll*f[i]*qpow(1-qpow(qpow(2,i),mod-2)+mod,mod-2)%mod;
  40. }
  41. for(int i=1;i<=3000;i++) f[i]=(f[i-1]+f[i])%mod;
  42. while(scanf("%d",&n)!=EOF) write(1ll*f[n]*qpow(n,mod-2)%mod);
  43. return 0;
  44. }

1006. Fantastic Magic Cube

首先考虑对于每个单位立方体开一个点,所有联通的立方体用一条边连起来,边权为点权之积。

那么切开一个大立方体相当于断掉一些变,取边权。

显然无论如何切答案都是一样的。

那么直接统计答案就好了,设\(N=n^3,a_i\)表示点权:

\[ans=\sum_{i=1}^{N}\sum_{j=i+1}^{N}a_ia_j=\dfrac{(\sum_{i=1}^{N}a_i)^2-\sum_{i=1}^{N}a_i^2}{2}
\]

那么用\(fwt\)求出每个权值出现了多少次,暴力算答案就好了。

复杂度\(O(n\log n)\)。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. void read(int &x) {
  4. x=0;int f=1;char ch=getchar();
  5. for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
  6. for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
  7. }
  8. void print(int x) {
  9. if(x<0) putchar('-'),x=-x;
  10. if(!x) return ;print(x/10),putchar(x%10+48);
  11. }
  12. void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}
  13. #define lf double
  14. #define pii pair<int,int >
  15. #define vec vector<int >
  16. #define pb push_back
  17. #define mp make_pair
  18. #define fr first
  19. #define sc second
  20. #define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++)
  21. const int maxn = 2e6+10;
  22. const int inf = 1e9;
  23. const lf eps = 1e-8;
  24. const int mod = 998244353;
  25. const int inv2 = 499122177;
  26. int f[maxn],n,N;
  27. void fwt(int *r,int op) {
  28. for(int i=1;i<N;i<<=1)
  29. for(int j=0;j<N;j+=i<<1)
  30. for(int k=0;k<i;k++) {
  31. int x=r[j+k],y=r[i+j+k];
  32. r[j+k]=(x+y)%mod,r[i+j+k]=(x-y+mod)%mod;
  33. if(op==-1) r[j+k]=1ll*r[j+k]*inv2%mod,r[i+j+k]=1ll*r[i+j+k]*inv2%mod;
  34. }
  35. }
  36. void solve() {
  37. for(N=1;N<=n;N<<=1);
  38. for(int i=0;i<n;i++) f[i]=1;
  39. for(int i=n;i<N;i++) f[i]=0;
  40. fwt(f,1);
  41. for(int i=0;i<N;i++) f[i]=1ll*f[i]*f[i]%mod*f[i]%mod;
  42. fwt(f,-1);int ans=0,tmp=0;
  43. for(int i=1;i<N;i++)
  44. ans=(ans+1ll*i*f[i]%mod)%mod,tmp=(tmp+1ll*i*i%mod*f[i]%mod)%mod;
  45. ans=1ll*ans*ans%mod;ans=(ans-tmp+mod)%mod;
  46. write(1ll*ans*inv2%mod);
  47. }
  48. int main() {
  49. while(scanf("%d",&n)!=EOF) solve();
  50. return 0;
  51. }

1008. Harmonious Army

二元组建图模板题。。。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define int long long
  4. void read(int &x) {
  5. x=0;int f=1;char ch=getchar();
  6. for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
  7. for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
  8. }
  9. void print(int x) {
  10. if(x<0) putchar('-'),x=-x;
  11. if(!x) return ;print(x/10),putchar(x%10+48);
  12. }
  13. void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}
  14. #define lf double
  15. #define pii pair<int,int >
  16. #define vec vector<int >
  17. #define pb push_back
  18. #define mp make_pair
  19. #define fr first
  20. #define sc second
  21. #define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++)
  22. const int maxn = 500+10;
  23. const int inf = 1e18;
  24. const lf eps = 1e-8;
  25. const int mod = 1e9+7;
  26. int head[maxn],tot=1,s,t,n,m,r[maxn][maxn],ans;
  27. struct edge{int to,nxt,w;}e[maxn*maxn];
  28. void add(int u,int v,int w) {e[++tot]=(edge){v,head[u],w},head[u]=tot;}
  29. void ins(int u,int v,int w) {add(u,v,w),add(v,u,0);}
  30. int dis[maxn];
  31. int bfs() {
  32. memset(dis,-1,sizeof dis);
  33. queue<int > q;q.push(s);dis[s]=0;
  34. while(!q.empty()) {
  35. int x=q.front();q.pop();
  36. for(int i=head[x];i;i=e[i].nxt)
  37. if(e[i].w>0&&dis[e[i].to]==-1) {
  38. dis[e[i].to]=dis[x]+1;
  39. if(e[i].to==t) return 1;
  40. q.push(e[i].to);
  41. }
  42. }return 0;
  43. }
  44. int dfs(int x,int flow) {
  45. if(x==t) return flow;
  46. int used=0;
  47. for(int v,i=head[x];i;i=e[i].nxt)
  48. if(dis[v=e[i].to]==dis[x]+1&&e[i].w>0) {
  49. int d=dfs(e[i].to,min(e[i].w,flow));
  50. e[i].w-=d,e[i^1].w+=d,used+=d,flow-=d;
  51. if(!flow) break;
  52. }
  53. if(!used) dis[x]=-1;
  54. return used;
  55. }
  56. int dinic() {int res=0;while(bfs()) res+=dfs(s,inf);return res;}
  57. void solve() {
  58. s=n+1,t=n+2;
  59. for(int i=1;i<=m;i++) {
  60. int u,v,a,b,c;read(u),read(v),read(a),read(b),read(c);
  61. ans-=(a+c)*2;
  62. r[s][u]+=c,r[s][v]+=c,r[v][t]+=a,r[u][t]+=a;
  63. r[u][v]+=a+c-b*2,r[v][u]+=a+c-b*2;
  64. }
  65. for(int i=1;i<=t;i++)
  66. for(int j=1;j<=t;j++)
  67. if(r[i][j]) ins(i,j,r[i][j]);
  68. write((-dinic()-ans)/2);
  69. }
  70. void clear() {
  71. tot=1;ans=0;
  72. memset(head,0,sizeof head);
  73. memset(r,0,sizeof r);
  74. }
  75. signed main() {
  76. while(scanf("%lld%lld",&n,&m)!=EOF) solve(),clear();
  77. return 0;
  78. }

1010. Just Skip The Problem

注意到最优一定是一位一位地问有没有,所以方案数直接就是阶乘。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. void read(int &x) {
  4. x=0;int f=1;char ch=getchar();
  5. for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
  6. for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
  7. }
  8. void print(int x) {
  9. if(x<0) putchar('-'),x=-x;
  10. if(!x) return ;print(x/10),putchar(x%10+48);
  11. }
  12. void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}
  13. #define lf double
  14. #define pii pair<int,int >
  15. #define vec vector<int >
  16. #define pb push_back
  17. #define mp make_pair
  18. #define fr first
  19. #define sc second
  20. #define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++)
  21. const int maxn = 1e6+10;
  22. const int inf = 1e9;
  23. const lf eps = 1e-8;
  24. const int mod = 1e6+3;
  25. int fac[maxn],n;
  26. int main() {
  27. fac[0]=1;
  28. for(int i=1;i<mod;i++) fac[i]=1ll*fac[i-1]*i%mod;
  29. while(scanf("%d",&n)!=EOF) write(n==2?2:(n>=mod?0:fac[n]));
  30. return 0;
  31. }

1011. Keen On Everything But Triangle

拿主席树维护区间,暴力判断就好了。

因为最劣的情况是构成斐波那契数列,而斐波那契增长是指数级的,所以最多在主席树上询问\(O(\log v)\)次,\(v\)是值域。

复杂度\(O(Tn\log n\log v)\)。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. void read(int &x) {
  4. x=0;int f=1;char ch=getchar();
  5. for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
  6. for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
  7. }
  8. void print(int x) {
  9. if(x<0) putchar('-'),x=-x;
  10. if(!x) return ;print(x/10),putchar(x%10+48);
  11. }
  12. void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}
  13. #define lf double
  14. #define pii pair<int,int >
  15. #define vec vector<int >
  16. #define pb push_back
  17. #define mp make_pair
  18. #define fr first
  19. #define sc second
  20. #define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++)
  21. const int maxn = 2e5+10;
  22. const int inf = 1e9;
  23. const lf eps = 1e-8;
  24. const int mod = 1e9+7;
  25. const int N = 1e9;
  26. int n,q,rt[maxn];
  27. struct persistance_segment_tree {
  28. int ls[maxn*40],rs[maxn*40],s[maxn*40],seg;
  29. void insert(int &p,int pre,int l,int r,int x) {
  30. p=++seg;ls[p]=ls[pre],rs[p]=rs[pre],s[p]=s[pre]+1;
  31. if(l==r) return ;int mid=(l+r)>>1;
  32. if(x<=mid) insert(ls[p],ls[pre],l,mid,x);
  33. else insert(rs[p],rs[pre],mid+1,r,x);
  34. }
  35. int query(int a,int b,int l,int r,int k) {
  36. if(l==r) return l;int mid=(l+r)>>1;
  37. if(s[rs[b]]-s[rs[a]]>=k) return query(rs[a],rs[b],mid+1,r,k);
  38. else return query(ls[a],ls[b],l,mid,k-(s[rs[b]]-s[rs[a]]));
  39. }
  40. void clear() {
  41. for(int i=1;i<=seg;i++) ls[i]=rs[i]=s[i]=0;
  42. seg=0;
  43. }
  44. }T;
  45. int find(int l,int r,int x) {return T.query(rt[l-1],rt[r],1,N,x);}
  46. #define ll long long
  47. void solve() {
  48. for(int i=1,x;i<=n;i++) read(x),T.insert(rt[i],rt[i-1],1,N,x);
  49. for(int i=1;i<=q;i++) {
  50. int l,r;read(l),read(r);
  51. if(r-l+1<3) {puts("-1");continue;}
  52. int a=find(l,r,1),b=find(l,r,2),c=find(l,r,3),x=3,bo=0;
  53. while(1) {
  54. if(a<b+c) {bo=1;printf("%lld\n",1ll*a+b+c);break;}
  55. if(x==r-l+1) break;
  56. a=b,b=c,c=find(l,r,++x);
  57. }if(!bo) puts("-1");
  58. }
  59. }
  60. void clear() {
  61. T.clear();
  62. for(int i=1;i<=n;i++) rt[i]=0;
  63. }
  64. int main() {
  65. while(scanf("%d%d",&n,&q)!=EOF) solve(),clear();
  66. return 0;
  67. }

1012. Longest Subarray

考虑排除不合法的情况,在剩下的情况取最大值。

那么对于每种颜色假设数量是\(x\),那么我们可以得到\(O(x)\)个形如当\(l\)在\(a\sim b\)之间时,\(r\)不能取\(c\sim d​\)的限制条件。

显然这可以转化成一个矩形。

那么直接扫描线就好了,复杂度\(O(Tn\log n)\)。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. void read(int &x) {
  4. x=0;int f=1;char ch=getchar();
  5. for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
  6. for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
  7. }
  8. void print(int x) {
  9. if(x<0) putchar('-'),x=-x;
  10. if(!x) return ;print(x/10),putchar(x%10+48);
  11. }
  12. void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}
  13. #define lf double
  14. #define pii pair<int,int >
  15. #define vec vector<int >
  16. #define pb push_back
  17. #define mp make_pair
  18. #define fr first
  19. #define sc second
  20. #define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++)
  21. #define iter vector<int > :: iterator
  22. const int maxn = 1e5+10;
  23. const int inf = 1e9;
  24. const lf eps = 1e-8;
  25. const int mod = 1e9+7;
  26. int n,c,k,cnt;
  27. vector<int > p[maxn];
  28. struct l {int x,l,r,v;}r[maxn<<3];
  29. void add(int x1,int x2,int y1,int y2) {
  30. if(x1>x2||y1>y2) return ;
  31. r[++cnt]=(l){x1,y1,y2,1};
  32. r[++cnt]=(l){x2+1,y1,y2,-1};
  33. }
  34. int cmp(l x,l y) {return x.x<y.x;}
  35. #define ls p<<1
  36. #define rs p<<1|1
  37. #define mid ((l+r)>>1)
  38. struct Segment_Tree {
  39. int mr[maxn<<2],tag[maxn<<2];
  40. void build(int p,int l,int r) {
  41. mr[p]=r;tag[p]=0;
  42. if(l==r) return ;
  43. build(ls,l,mid),build(rs,mid+1,r);
  44. }
  45. void update(int p,int l,int r) {
  46. if(tag[p]) mr[p]=-1;
  47. else if(mr[rs]!=-1) mr[p]=mr[rs];
  48. else mr[p]=mr[ls];
  49. }
  50. void cover(int p,int l,int r,int x,int y,int v) {
  51. if(x<=l&&r<=y) {
  52. tag[p]+=v;
  53. if(l==r) mr[p]=tag[p]?-1:r;
  54. else update(p,l,r);
  55. return ;
  56. }
  57. if(x<=mid) cover(ls,l,mid,x,y,v);
  58. if(y>mid) cover(rs,mid+1,r,x,y,v);
  59. update(p,l,r);
  60. }
  61. }T;
  62. void solve() {
  63. T.build(1,1,n);cnt=0;
  64. for(int i=1;i<=c;i++) p[i].clear();
  65. for(int i=1,x;i<=n;i++) read(x),p[x].pb(i);
  66. for(int i=1;i<=c;i++)
  67. if(p[i].size()<k) {
  68. for(iter x=p[i].begin();x!=p[i].end();x++)
  69. add(1,*x,*x,n);
  70. } else {
  71. int sz=p[i].size();
  72. add(1,p[i][0],p[i][0],p[i][k-1]-1);
  73. for(int x=0;x<sz-1;x++) add(p[i][x]+1,p[i][x+1],p[i][x+1],x+k>=sz-1?n:p[i][x+k+1]-1);
  74. }
  75. sort(r+1,r+cnt+1,cmp);int t=1,ans=0;
  76. for(int i=1;i<=n;i++) {
  77. while(r[t].x==i) T.cover(1,1,n,r[t].l,r[t].r,r[t].v),t++;
  78. if(T.mr[1]<=i) continue;
  79. ans=max(ans,T.mr[1]-i+1);
  80. }write(ans);
  81. }
  82. int main() {
  83. while(scanf("%d%d%d",&n,&c,&k)!=EOF) solve();
  84. return 0;
  85. }

HDU校赛 | 2019 Multi-University Training Contest 2的更多相关文章

  1. HDU校赛 | 2019 Multi-University Training Contest 6

    2019 Multi-University Training Contest 6 http://acm.hdu.edu.cn/contests/contest_show.php?cid=853 100 ...

  2. HDU校赛 | 2019 Multi-University Training Contest 5

    2019 Multi-University Training Contest 5 http://acm.hdu.edu.cn/contests/contest_show.php?cid=852 100 ...

  3. HDU校赛 | 2019 Multi-University Training Contest 4

    2019 Multi-University Training Contest 4 http://acm.hdu.edu.cn/contests/contest_show.php?cid=851 100 ...

  4. HDU校赛 | 2019 Multi-University Training Contest 3

    2019 Multi-University Training Contest 3 http://acm.hdu.edu.cn/contests/contest_show.php?cid=850 100 ...

  5. HDU校赛 | 2019 Multi-University Training Contest 1

    2019 Multi-University Training Contest 1 http://acm.hdu.edu.cn/contests/contest_show.php?cid=848 100 ...

  6. hdu 4930 Fighting the Landlords--2014 Multi-University Training Contest 6

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4930 Fighting the Landlords Time Limit: 2000/1000 MS ...

  7. HDU 6143 - Killer Names | 2017 Multi-University Training Contest 8

    /* HDU 6143 - Killer Names [ DP ] | 2017 Multi-University Training Contest 8 题意: m个字母组成两个长为n的序列,两序列中 ...

  8. HDU 6074 - Phone Call | 2017 Multi-University Training Contest 4

    看标程的代码这么短,看我的.... 难道是静态LCA模板太长了? /* HDU 6074 - Phone Call [ LCA,并查集 ] | 2017 Multi-University Traini ...

  9. HDU 6068 - Classic Quotation | 2017 Multi-University Training Contest 4

    /* HDU 6068 - Classic Quotation [ KMP,DP ] | 2017 Multi-University Training Contest 4 题意: 给出两个字符串 S[ ...

随机推荐

  1. 【Spring Boot】Spring Boot之使用AOP实现数据库多数据源自动切换

    一.添加maven坐标 <!-- aop --> <dependency> <groupId>org.springframework.boot</groupI ...

  2. Websocket --socket.io的用法

    <!DOCTYPE html> <html> <head> <title>Hello WebSocket</title> <link ...

  3. Consul 学习资料

    资料 网址 Consul 入门指南 https://book-consul-guide.vnzmi.com/

  4. 负载均衡环境:nginx + 2tomcat

    部署两个服务 安装两个tomcat,tomcat安装,参考:https://www.cnblogs.com/uncleyong/p/10742650.html 两个tomcat的端口要不一样(shut ...

  5. LeetCode 489. Robot Room Cleaner

    原题链接在这里:https://leetcode.com/problems/robot-room-cleaner/ 题目: Given a robot cleaner in a room modele ...

  6. es6 Class类的使用

    es6新增了一种定义对象实例的方法,使用class关键字定义类,与class相关的知识点也逐步火热起来,但是部分理解起来相对抽象,简单对class相关的知识点进行总结,更好的使用class. 关于类有 ...

  7. JavaScript计算时间前一天跟后一天

    1.获取当前时 //写在HTML <button onclick="goBefore()">前一天</button> <button onclick= ...

  8. es4x 调用其他三方jar 包

    es4x 使用了graalvm 作为运行时环境,所以即拥有vertx 的强大,又拥有了与java 代码便捷的通信能力 以下是一个简单的测试,同时也简单说明下es4x 的es4x-launcher.ja ...

  9. python paramiko的使用介绍

    一: 使用paramiko #设置ssh连接的远程主机地址和端口t=paramiko.Transport((ip,port))#设置登录名和密码t.connect(username=username, ...

  10. [BZOJ1015/JSOI2008]星球大战

    // 此博文为迁移而来,写于2015年7月16日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w6le.html 1.题 ...