2018 Multi-University Training Contest 3 Solution(咕咕咕)

emmm,wuyiqi说要补题


2018 Multi-University Training Contest 3 Solution

(如果排版不好请戳原题6319~6331)

Problem A. Ascending Rating

Time Limit: 10000/5000 MS (Java/Others)
Memory Limit: 524288/524288 K (Java/Others)

Problem Description
Before the start of contest, there are n n n ICPC contestants waiting in a long queue. They are labeled by 1 to n from left to right. It can be easily found that the i i i-th contestant’s QodeForces rating is a i a_i ai.
Little Q, the coach of Quailty Normal University, is bored to just watch them waiting in the queue. He starts to compare the rating of the contestants. He will pick a continous interval with length m m m, say [ l , l + m − 1 ] [l,l+m−1] [l,l+m1], and then inspect each contestant from left to right. Initially, he will write down two numbers m a x r a t i n g = − 1 maxrating=−1 maxrating=1 and c o u n t = 0 count=0 count=0. Everytime he meets a contestant k with strictly higher rating than maxrating, he will change maxrating to a k a_k ak and c o u n t count count to c o u n t + 1 count+1 count+1.
Little T is also a coach waiting for the contest. He knows Little Q is not good at counting, so he is wondering what are the correct final value of m a x r a t i n g maxrating maxrating and count. Please write a program to figure out the answer.

Input
The first line of the input contains an integer T ( 1 ≤ T ≤ 2000 ) T(1≤T≤2000) T(1T2000), denoting the number of test cases.
In each test case, there are 7 integers n , m , k , p , q , r , M O D ( 1 ≤ m , k ≤ n ≤ 107 , 5 ≤ p , q , r , M O D ≤ 109 ) n,m,k,p,q,r,MOD(1≤m,k≤n≤107,5≤p,q,r,MOD≤109) n,m,k,p,q,r,MOD(1m,kn107,5p,q,r,MOD109) in the first line, denoting the number of contestants, the length of interval, and the parameters k , p , q , r , M O D k,p,q,r,MOD k,p,q,r,MOD.
In the next line, there are k k k integers a 1 , a 2 , . . . , a k ( 0 ≤ a i ≤ 109 ) a_1,a_2,...,a_k(0≤a_i≤109) a1,a2,...,ak(0ai109), denoting the rating of the first k k k contestants.
To reduce the large input, we will use the following generator. The numbers p , q , r p,q,r p,q,r and M O D MOD MOD are given initially. The values a i ( k &lt; i ≤ n ) a_i(k&lt;i≤n) ai(k<in) are then produced as follows :
a i = ( p × a i − 1 + q × i + r ) m o d M O D a_i=(p×a_i−1+q×i+r)modMOD ai=(p×ai1+q×i+r)modMOD
It is guaranteed that ∑ n ≤ 7 × 107 ∑n≤7×107 n7×107 and ∑ k ≤ 2 × 106 ∑k≤2×106 k2×106.

Output
Since the output file may be very large, let’s denote maxratingi and counti as the result of interval [i,i+m−1].
For each test case, you need to print a single line containing two integers A and B, where :
A = ∑ i = 1 n − m + 1 ( m a x r a t i n g i ⊕ i ) A=\sum^{n-m+1}_{i=1}(maxrating_i⊕i) A=i=1nm+1(maxratingii)
B = ∑ i = 1 n − m + 1 ( c o u n t i ⊕ i ) B=\sum^{n-m+1}_{i=1}(count_i⊕i) B=i=1nm+1(countii)

Note that ``⊕’’ denotes binary XOR operation.

Sample Input

1
10 6 10 5 5 5 5
3 2 2 1 5 7 6 8 2 9

Sample Output

46 11

按照 r 从 m 到 n 的顺序很难解决这个问题。
考虑按照 r 从 n 到 m 的顺序倒着求出每个区间的答案。
按照滑窗最大值的经典方法维护 a 的单调队列,那么队列中的元素个数就是最大值的变化次数。
时间复杂度 O ( n ) O(n) O(n)
[Code]


[标程]

#include<cstdio>
const int N=10000010;
int T,n,m,k,P,Q,R,MOD,i,a[N],q[N],h,t;long long A,B;
int main(){
  scanf("%d",&T);
  while(T--){
    scanf("%d%d%d%d%d%d%d",&n,&m,&k,&P,&Q,&R,&MOD);
    for(i=1;i<=k;i++)scanf("%d",&a[i]);
    for(i=k+1;i<=n;i++)a[i]=(1LL*P*a[i-1]+1LL*Q*i+R)%MOD;
    for(h=1,t=A=B=0,i=n;i;i--){
      while(h<=t&&a[q[t]]<=a[i])t--;
      q[++t]=i;
      if(i+m-1<=n){
        while(q[h]>=i+m)h++;
        A+=i^a[q[h]];
        B+=i^(t-h+1);
      }
    }
    printf("%lld %lld\n",A,B);
  }
}

Problem D. Euler Function

Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 524288/524288 K (Java/Others)
Problem Description
In number theory, Euler’s totient function φ(n) counts the positive integers up to a given integer n that are relatively prime to n. It can be defined more formally as the number of integers k in the range 1≤k≤n for which the greatest common divisor gcd(n,k) is equal to 1.
For example, φ(9)=6 because 1,2,4,5,7 and 8 are coprime with 9. As another example, φ(1)=1 since for n=1 the only integer in the range from 1 to n is 1 itself, and gcd(1,1)=1.
A composite number is a positive integer that can be formed by multiplying together two smaller positive integers. Equivalently, it is a positive integer that has at least one divisor other than 1 and itself. So obviously 1 and all prime numbers are not composite number.
In this problem, given integer k, your task is to find the k-th smallest positive integer n, that φ(n) is a composite number.
Input
The first line of the input contains an integer T(1≤T≤100000), denoting the number of test cases.
In each test case, there is only one integer k(1≤k≤109).
Output
For each test case, print a single line containing an integer, denoting the answer.

Sample Input

2
1
2

Sample Output

5
7

可以发现Euler Function 有一些性质
Euler Function
除了前两项外都是偶数(证明略)
于是只要特判前两项就好

#include <cstdio>
using namespace std;
int main() {
	int t, k;
    scanf("%d", &t);
    for (int i = 1; i <= t; i++) {
        scanf("%d", &k);
        if (k == 1) printf("5\n");
        else if (k == 2) printf("7\n");
        else printf("%d\n", k + 5);
    }
    return 0;
}

Problem F. Grab The Tree

Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 524288/524288 K (Java/Others)
Problem Description
Little Q and Little T are playing a game on a tree. There are n vertices on the tree, labeled by 1,2,…,n, connected by n−1 bidirectional edges. The i-th vertex has the value of wi.
In this game, Little Q needs to grab some vertices on the tree. He can select any number of vertices to grab, but he is not allowed to grab both vertices that are adjacent on the tree. That is, if there is an edge between x and y, he can’t grab both x and y. After Q’s move, Little T will grab all of the rest vertices. So when the game finishes, every vertex will be occupied by either Q or T.
The final score of each player is the bitwise XOR sum of his choosen vertices’ value. The one who has the higher score will win the game. It is also possible for the game to end in a draw. Assume they all will play optimally, please write a program to predict the result.
Input
The first line of the input contains an integer T(1≤T≤20), denoting the number of test cases.
In each test case, there is one integer n(1≤n≤100000) in the first line, denoting the number of vertices.
In the next line, there are n integers w1,w2,…,wn(1≤wi≤109), denoting the value of each vertex.
For the next n−1 lines, each line contains two integers u and v, denoting a bidirectional edge between vertex u and v.
Output
For each test case, print a single line containing a word, denoting the result. If Q wins, please print Q. If T wins, please print T. And if the game ends in a draw, please print D.

Sample Input

1
3
2 2 2
1 2
1 3

Sample Output

Q

感性分析T是不可能赢的
a l l = w 1 x o r w 2 x o r . . . x o r w n all=w_1 xor w_2 xor ... xor w_n all=w1xorw2xor...xorwn
如果 a l l = 0 all=0 all=0,即xor相等,draw
否则Q只要取到有all最高位的那个 w [ i ] w[i] w[i],Q wins

#include <cstdio>
#define N 100010
using namespace std;
int w[N];
int main() {
	int t;
	scanf("%d", &t);
	while(t--) {
		int n, all = 0;
		scanf("%d", &n);
		for (int i = 1; i <= n; ++i) {
			scanf("%d", &w[i]);
			all ^= w[i];
		}
		int a, b;
		for (int i = 1; i < n; ++i) scanf("%d%d", &a, &b);
		if (all == 0) printf("D\n");
		else printf("Q\n");
	}
	return 0;
}

Problem L. Visual Cube

Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 524288/524288 K (Java/Others)
Problem Description
Little Q likes solving math problems very much. Unluckily, however, he does not have good spatial ability. Everytime he meets a 3D geometry problem, he will struggle to draw a picture.
Now he meets a 3D geometry problem again. This time, he doesn’t want to struggle any more. As a result, he turns to you for help.
Given a cube with length a, width b and height c, please write a program to display the cube.
Input
The first line of the input contains an integer T(1≤T≤50), denoting the number of test cases.
In each test case, there are 3 integers a,b,c(1≤a,b,c≤20), denoting the size of the cube.
Output
For each test case, print several lines to display the cube. See the sample output for details.

Sample Input

2
1 1 1
6 2 4

Sample Output

..+-+
././|
+-+.+
|.|/.
+-+..
....+-+-+-+-+-+-+
.../././././././|
..+-+-+-+-+-+-+.+
./././././././|/|
+-+-+-+-+-+-+.+.+
|.|.|.|.|.|.|/|/|
+-+-+-+-+-+-+.+.+
|.|.|.|.|.|.|/|/|
+-+-+-+-+-+-+.+.+
|.|.|.|.|.|.|/|/.
+-+-+-+-+-+-+.+..
|.|.|.|.|.|.|/...
+-+-+-+-+-+-+....

纯模拟,下面是dalaoCHY的代码

#include <cstdio>
using namespace std;
char ch[100][100];
int a, b, c;
void work() {
    scanf("%d%d%d", &a, &b, &c);
    for(int i = 1; i <= (c + b) * 2 + 1; i++)
        for(int j = 1; j <= (a + b) * 2 + 1; j++)
            ch[i][j] = '.';
    for(int i = 1; i <= c; i++) {
        for(int j = 1; j <= a; j++) {
            ch[b * 2 + 1 + (i - 1) * 2][(j - 1) * 2 + 1] = '+';
            ch[b * 2 + 1 + (i - 1) * 2][(j - 1) * 2 + 2] = '-';
        }
        ch[b * 2 + 1 + (i - 1) * 2][a * 2 + 1] = '+';
        for(int j = 1; j <= a; j++) ch[b * 2 + 2 + (i - 1) * 2][(j - 1) * 2 + 1] = '|';
        ch[b * 2 + 2 + (i - 1) * 2][a * 2 + 1] = '|';
    }
    for(int j = 1; j <= a; j++) {
        ch[(b + c) * 2 + 1][(j - 1) * 2 + 1] = '+';
        ch[(b + c) * 2 + 1][(j - 1) * 2 + 2] = '-';
    }
    ch[(b + c) * 2 + 1][a * 2 + 1] = '+';
    for(int i = 1; i <= b; i++) {
        for(int j = 1; j <= a; j++) {
            ch[(i - 1) * 2 + 1][(j - 1) * 2 + 1 + b * 2 - (i - 1) * 2] = '+';
            ch[(i - 1) * 2 + 1][(j - 1) * 2 + 2 + b * 2 - (i - 1) * 2] = '-';
        }
        ch[(i - 1) * 2 + 1][a * 2 + 1 + b * 2 - (i - 1) * 2] = '+';
        for(int j = 1; j <= a; j++) {
            ch[(i - 1) * 2 + 2][(j - 1) * 2 + b * 2 - (i - 1) * 2] = '/';
        }
        ch[(i - 1) * 2 + 2][a * 2 + b * 2 - (i - 1) * 2] = '/';
    }
    for(int i = 1; i <= b; i++) {
        for(int j = 1; j <= c; j++) {
            ch[j * 2 + (i - 1) * 2][(a + b) * 2 + 1 - (i - 1) * 2] = '|';
            ch[j * 2 + 1 + (i - 1) * 2][(a + b) * 2 + 1 - (i - 1) * 2] = '+';
        }
        for(int j = 1; j <= c; j++) {
            ch[j * 2 + 2 + (i - 1) * 2][(a + b) * 2 + 1 - (i - 1) * 2 - 1] = '/';
        }
    }
    for(int i = 1; i <= (c + b) * 2 + 1; i++){
        for(int j = 1; j <= (a + b) * 2 + 1; j++) printf("%c", ch[i][j]); printf("\n");
    }
    return;
}
int main() {
    int t;
    scanf("%d", &t);
    for(int i = 1; i <= t; i++) work();
    return 0;
}
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值