2018 Multi-University Training Contest 3 杭电多校第三场
躺了几天 终于记得来填坑了
1001 Ascending Rating (hdoj 6319)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6319
单调队列 具体有点类似双端队列滑动窗口
题意:在一个队列中 每次都给定一个固定长度的区间 从i=1开始向后移动 每次在这个区间中进行a[i]和a[j]的比较 若a[i]<a[j] count++ 最大值更新为a[j] ,每个区间的最大值和count都分别异或i 求出分别的和
求区间最大值可以比较容易的想到单调队列 在求count的时候 正向求难以在规定的时间内求得 想到的做法是从后往前使用双端队列 因为这题谜之卡常 从头一个队列从尾一个队列 两个队列就超时 将两个都从尾部扫
代码如下
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; const int maxn=1e7+10; long long a[maxn],qq[maxn]; int main(){ int t,n,m,k; long long p,q,r,mod; scanf("%d",&t); while(t--){ int head=0,tail=0; scanf("%d%d%d%lld%lld%lld%lld",&n,&m,&k,&p,&q,&r,&mod); for(int i=1;i<=k;i++) scanf("%lld",&a[i]); for(int i=k+1;i<=n;i++) a[i]=((a[i-1]*p)%mod+(q*i)%mod+r)%mod; for(int i=n;i>=n-m+1;i--){ while(head<tail&&a[qq[tail-1]]<=a[i]) tail--; qq[tail++]=i; } long long ans=0,cnt=0; ans+=a[qq[head]]^(n-m+1); cnt+=(tail-head)^(n-m+1); for(int i=n-m;i>=1;i--){ while(qq[head]>i+m-1&&head<tail) ++head; while(head<tail&&a[qq[tail-1]]<=a[i]) --tail; qq[tail++]=i; ans+=a[qq[head]]^i; cnt+=(tail-head)^i; } printf("%lld %lld\n",ans,cnt); } return 0; }
1004 Euler Function (hdoj 6322)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6322
签到题
题意:给出了欧拉函数的定义 求欧拉函数为合数的第k个数是什么
题目说的有点绕 但是看懂了 就是在介绍欧拉函数 在数论中 对于正整数N,少于或等于N ([1,N]) 且与N互质的正整数(包括1)的个数 记作φ(n) 即为欧拉函数
这是一题假的数论题 可以打个表找个规律 发现第一个合数为5 第二个为7 之后第三个数就是k+5
代码如下
#include<cstdio> #include<algorithm> #include<cstring> #include<iostream> using namespace std; int main(){ int t,k; scanf("%d",&t); while(t--){ scanf("%d",&k); if(k==1) printf("5\n"); if(k==2) printf("7\n"); if(k>=3) printf("%d\n",k+5); } return 0; }
1006 Grab The Tree (hdoj 6324)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6324
签到题
除了异或和为0是平手 其余情况都是先手必胜
代码如下
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int maxn = 1e6 + 10; int a[maxn]; int main(){ int t, n, u, v, sum; scanf("%d", &t); while (t--){ scanf("%d", &n); sum = 0; for (int i = 0; i < n; i++){ scanf("%d", &a[i]); sum ^= a[i]; } for (int i = 0; i < n-1; i++){ scanf("%d%d", &u, &v); } if(sum == 0) printf("D\n"); else printf("Q\n"); } return 0; }
1012 Visual Cube (hdoj 6330)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6330
签到题 模拟题
题意:根据题意 给出了长方体的长宽高 模拟出长方体
难度不大 但是非常麻烦并且让人头疼……
代码如下
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=110; char mp[maxn][maxn]; int t,a,b,c,m,n; int main(){ scanf("%d",&t); while(t--){ scanf("%d%d%d",&a,&b,&c); n=2*c+1+2*b; m=2*a+1+2*b; //初始化 for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ mp[i][j]='.'; } } //上方 +-的构造 for(int i=1;i<=2*b;i+=2){ for(int j=2*b-i+2;j<=2*a+2*b-i+2;j++){ if(j%2==1) mp[i][j]='+'; else mp[i][j]='-'; } for(int j=2*a+2*b-i+2+2;j<=m;j++){ if(j%2==1) mp[i][j]='+'; } } //| /的构造 for(int i=2;i<=2*b;i+=2){ for(int j=2*b-i+2;j<=m;j++){ if(j%2==0) mp[i][j]='/'; } for(int j=m;j>=m-i+2;j-=2){ mp[i][j]='|'; } } for(int i=2*b+2;i<=n;i+=2){ for(int j=1;j<=m;j+=2){ mp[i][j]='|'; } for(int j=2*a+2;j<=m;j+=2){ mp[i][j]='/'; } } //下方的+-构造 for(int i=2*b+1;i<=2*c+1;i+=2){ for(int j=1;j<=2*a+1;j++){ if(j%2==1) mp[i][j]='+'; else mp[i][j]='-'; } for(int j=2*a+2;j<=m;j++){ if(j%2==1) mp[i][j]='+'; } } for(int i=n;i>2*c+1;i-=2){ for(int j=1;j<=2*a+1;j++){ if(j%2==1) mp[i][j]='+'; else mp[i][j]='-'; } for(int j=2*a+2;j<=m;j++){ if(j%2==1) mp[i][j]='+'; } } int pos=0; for(int i=1;i<2*b+1;i++){ for(int j=1;j<=2*b+1-i;j++){ mp[i][j]='.'; } } for(int i=n;i>2*c+1;i--){ for(int j=2*a+2+pos;j<=m;j++){ mp[i][j]='.'; } pos++; } //输出 for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ printf("%c",mp[i][j]); } printf("\n"); } } return 0; }