Test on 11/24/2018

偶然间最糟糕的再会

Description

一天Murphyc从睡梦中醒来,发现自己居然穿越到了弹丸论破的世界。作为原作全成就通关的超高校级Gamer,Murphyc很清楚接下来会发生什么。为了中止Chiaki即将面临的“学级裁判”,Murphyc溜进了未来机关内部,但是只有持有特定编号的识别卡才能进入机关控制室。
好在,Murphyc其实还有另一重身份----法师学徒!虽然Murphyc手中只有门口警卫的识别卡,但机智的他发现该警卫的识别卡编号只要经过若干次Magic操作便可变为原作CG中某重要角色Chisa的的识别码。
Magic操作:对于i与j位置的两个数字你可以消耗|i-j|的魔力值以交换两个数字的位置。
例如
现在已知警卫的识别码为一个长度为n的整数序列a,ai<=n, Chisa的识别码为长度为n的整数序列b,bi<=n,并且,a、b序列均为[1,n]的全排列之一.为了节约魔力,请问Murphyc至少要消耗多少魔力才能获得Chisa的识别码?

Input

第一行一个数字T代表测试的组数(T<=20)
对于每组测试,第一行一个数字n代表序列的长度(n<=2e5)
接下来一行有n个数字a1,a2,a3….an(1<=ai<=n)
接下来一行有n个数字b1,b2,b3…bn(1<=bi<=n)

Output

对于每行输出一个整数

Examples

Input

1
4
2 3 4 1
1 3 4 2

Output

3

 

正确解法:

官方题解:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 int a[200005],b[200005];
 5 int conv[200005];
 6 int main()
 7 {
 8     freopen("stdin.txt","r",stdin);
 9     freopen("stdout.txt","w",stdout);
10     int zu;
11     scanf("%d",&zu);
12     while(zu--)
13     {
14         int n;
15         scanf("%d",&n);
16         for(int i=1;i<=n;i++) scanf("%d",&a[i]),conv[a[i]]=i;
17         for(int i=1;i<=n;i++) scanf("%d",&b[i]);
18         ll ans=0;
19         for(int i=1;i<=n;i++) ans+=abs(i-conv[b[i]]);
20         printf("%lld\n",ans/2);
21     }
22 }
View Code

(为什么这样写我也不知道qaq)

 

01串

Description

现在我们有一个由01组成的字符串。我们需要在上面做一些操作。每次我们都选一个“01”子串,把他替换成110。如果找不到“01”子串,那么操作结束。请输出总共进行了多少次操作,结果请mod 1e9+7。

Ps:“01”子串必须是相邻的0和1,字符串中只包含0和1。

Input

首先一个T,代表接下来有T行。

接下来的T行,每行一个字符串str

(1<= T <= 200, 所有字符串长度和 len <= 2e7)

Output

对于每个字符串,输出相应操作数。

Examples

Input

2
01
001

Output

1
3

 

正确解法:

每个字符串都会变成前面是1,后面是0,若在1前面有一个0,那么需要1次。有两个0,需要3次,有n个0,需要(2*n-1)次,若有两个1,你会发现,第一个1变化后,所以第一个1前面的0都变到了第二个1的前面。

所有就统计0个个数,遇到1就加一次。

 

 

粗题⼈不考你没学过的算法

Description

粗题⼈症重承诺此题不考你没学过的算法

给你⼀个区间[L,R]

需要选择N个数,这N个数都在这个区间范围内

那么我们知道⼀共有[R-L+1]^N种选法

假如我们想要这N个数的最⼤公约数恰好是K

请问⼀共有多少种选法,输出答案对1e9+7取模

Input

 多组测试数据 对于每组数据,输⼊⼀⾏包含4个整数N,K,L,R(1<=N,K,L<=10^9,L<=R<=10^9)

(0<=R-L<=10^5)

Output

对于每行输出一个整数

Examples

Input

2 2 2 4
2 100 2 4
1 5 5 5
73824 17347 9293482 9313482
222 222 222 22222

Output

3
0
1
0
339886855

 

正确解法:

不会qaq 挖坑。

 1 #include <iostream> 
 2 #include <fstream> 
 3 #include <sstream> 
 4 #include <cstdio> 
 5 #include <cstring> 
 6 #include <cstdlib> 
 7 #include <cmath> 
 8 #include <ctime> 
 9 #include <algorithm> 
10 #include <vector> 
11 #include <queue> 
12 #include <deque> 
13 #include <stack> 
14 #include <set> 
15 #include <map> 
16 #include <complex> 
17 #include <bitset> 
18 #include <iomanip> 
19 #include <utility> 
20  
21 using namespace std; 
22  
23 typedef long long LL; 
24 typedef pair<int,int> pii; 
25 typedef complex<double> point; 
26  
27 const int mod = 1000000007; 
28  
29 int f[200000]; 
30  
31 int POW (int base, int p){ 
32   int ret = 1, cur = base; 
33   while (p){ 
34     if (p & 1) ret = (LL)ret * cur % mod; 
35     p>>=1; 
36     cur = (LL)cur * cur % mod; 
37   } 
38   return ret; 
39 } 
40  
41 struct RandomGCD{ 
42   int countTuples(int N, int K, int lo, int hi){ 
43       memset(f, 0, sizeof(f));
44     lo = (lo+K-1)/K, hi = hi/K;  
45     if (lo > hi) 
46       return 0; 
47     for (int i=100000; i>=1; i--){ 
48       int L = (lo + i-1) / i; 
49       int H = hi / i; 
50       if (L <= H){ 
51         f[i] = POW(H-L+1, N);  
52         f[i]-= (H-L+1); 
53         if (f[i] < 0) f[i]+= mod; 
54         for (int j=i*2; j<=100000; j+=i){ 
55           f[i]-=f[j]; 
56           if (f[i]<0) f[i]+= mod; 
57         } 
58       } 
59     } 
60     if (lo == 1) 
61       f[1] = (f[1] + 1) % mod; 
62     return f[1]; 
63   }   
64 };
65  
66 int main() {
67     RandomGCD test;
68     int N, K, L, R;
69     while (cin >> N >> K >> L >> R) {
70         cout << test.countTuples(N, K, L, R) << endl;
71     }
72     return 0;
73 }
View Code

 

 

平方排列

Description

 给你一个n,问能否将1到n这n个整数进行排列,使得这个排列中任意两个相邻的数字和都是平方数。如果能,输出这个排列(如果存在多个,输出字典序最小的),否则输出-1。

Input

 输入一个整数n (1 <= n <= 15)

Output

 如果存在这样的排列(如果存在多个,输出字典序最小的),输出n个以空格隔开的整数表示这个排列,否则输出-1。

Examples

Input

1

Output

1

 

正确解法:

这题想一想就知道,只有1和15.

但我们还是要用dfs,我还是不熟啊,变量有点多,有点复杂。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<string>
 4 #include<cstring>
 5 #include<map>
 6 #include<algorithm>
 7 #include<cmath>
 8 using namespace std;
 9 int n,a[20], book[20], flag = 0;
10 void dfs(int k)
11 {
12     if (k == n + 1)
13     {
14         flag = 1;
15         for (int i = 1; i < n; i++)
16             cout << a[i] << " ";
17         cout << a[n] << endl;
18         return ;
19     }
20     for (int i = 1; i <= n; i++)
21     {
22         int tmp = (int)sqrt(i + a[k - 1]);
23         if (k>1&&i + a[k - 1] != tmp * tmp)
24             continue;
25         if (book[i] == 0&&flag==0)
26         {
27             book[i] = 1;
28             a[k] = i;
29             dfs(k + 1);
30             book[i] = 0;
31         }
32     }
33 }
34 int main()
35 {
36     flag = 0;
37     cin >> n;
38     dfs(1);
39     if (flag == 0)    cout << -1 << endl;
40     return 0;
41 }
View Code

除了第一个数,保证后面的数都与前面的数形成平方数。

最后找到n个输出就好了。

 

四色图

Description

 Perfectxx给LZH出了一道题,要LZH构造出一个尽可能大的四色图。所谓的四色图指的是由n个点m条边组成的无向图。其中,每个点要么是红色,要么是蓝色,每条边要么是黑色,要么是白色。

黑边能连接两个红点,或是一个红点与一个蓝点。而白边只能连接红点与蓝点。

LZH构造出了一个图,但是委托给Murphyc,让他去打印的时候,Murphyc用了黑白打印机。现在分不清楚顶点的颜色是红还是蓝。

现在你需要帮Perfectxx检查一下,LZH构造出的图有没有可能是四色图。

Input

第一行输入n和m,表示点的数量和边的数量 (1<=n,m<=2e5)

接下来的m行,每行三个输入 w u v 表示图中有一条从u到v的无向边,w=1时表示

这条边是黑边,w=0是表示这条边是白边。

Output

仅输出一行字符串,其中”Maybe”表示原图有可能是四色图,”Impossible”表示原图一定不是四色图。(输出中没有引号)

Examples

Input

4 4
0 1 2
0 2 3
0 3 4
0 4 1
3 3
0 1 2
0 2 3
0 3 1

Output

Maybe
Impossible

 

正确解法:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=500000;
 4 int ins[N],dfn[N],low[N],cnt,sta[N];
 5 int top,v,u;
 6 int Next[N],head[N],to[N];
 7 int tot;
 8 int scc[N];
 9 int scccnt;
10 void make_list(int u,int v){
11     Next[++tot]=head[u],head[u]=tot,to[tot]=v;
12 }
13 void tarjan(int x){
14     ins[x]=dfn[x]=low[x]=++cnt,sta[top++]=x;
15     for(int p=head[x],v=to[p];p;p=Next[p],v=to[p])
16         if(!dfn[v])tarjan(v),low[x]=min(low[x],low[v]);
17         else if(ins[v])low[x]=min(low[x],dfn[v]);
18     if(low[x]==dfn[x]){
19         scc[x]=++scccnt,ins[x]=0;
20         while((u=sta[--top])!=x)ins[u]=0,scc[u]=scccnt;
21     }
22 }
23 int main(){
24     int n,m,w,u,v;
25     freopen("data5.in","r",stdin);
26     freopen("data5.out","w",stdout);    
27     scanf("%d%d",&n,&m); 
28     for(int i=1;i<=m;i++){
29         scanf("%d%d%d",&w,&u,&v);
30         if(!w){
31             make_list(u,v+n);
32             make_list(v,u+n);
33             make_list(u+n,v);
34             make_list(v+n,u);
35         }
36         else{
37             make_list(u+n,v);
38             make_list(v+n,u);
39         }
40     }
41     
42     for(int i=1;i<=2*n;i++){
43         if(!dfn[i])tarjan(i);
44     }
45     bool ok=1;
46     for(int i=1;i<=n;i++){
47         ok&=(scc[i]!=scc[i+n]);
48     }
49     if(ok)puts("Maybe");
50     else puts("Impossible");
51     return 0; 
52 } 
View Code

 

最大化

Description

 给你n个整数,请重新排列这些整数,使得式子的值最大,其中表示第i个整数。请输出S的最大值。

Input

第一行一个整数n(2 <= n <= 100000),表示数字的个数;

第二行为n个整数 (1 <= ai <= 1000000000)

Output

输出一个整数,表示S的最大值。

Examples

Input

2
2 1

Output

1

 

正确解法:

Smax = (-1)^2 * (2 – 1) = 1

简单模拟一下,找到奇数和偶数的不同

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<string>
 4 #include<cstring>
 5 #include<map>
 6 #include<algorithm>
 7 #include<cmath>
 8 using namespace std;
 9 int n;
10 long long a[100100],sum=0;
11 int main()
12 {
13     cin >> n;
14     for (int i = 1; i <= n; i++)
15         cin >> a[i];
16     sort(a + 1, a + n + 1);
17     if (n % 2 == 0)
18     {
19         for (int i = n / 2 + 1; i <= n; i++)
20             sum += 2*a[i];
21         for (int i = 1; i <= n / 2; i++)
22             sum -= 2*a[i];
23         sum = sum - a[n / 2 + 1] +a[n / 2];
24     }
25     else
26     {
27         for (int i = n / 2 + 2; i <= n; i++)
28             sum += 2*a[i];
29         for (int i = 1; i <= n / 2; i++)
30             sum -= 2*a[i];
31         sum = sum - a[n / 2 + 1] - a[n / 2 - 2];
32     }
33     cout << sum << endl;
34     return 0;
35 }
View Code

 

调整队列

Description

这天小g遇到了一个队列,小g觉得队列乱糟糟的不好看。于是小g希望将队列调整成为一个等差数列(差可为0)。但是小g对每个数都最多调整一次,每次可以对这个数加一、减一。请你帮助小g解决这个问题,如果能调整出等差队列,输出需要调整的数的最小数量,否则输出-1。

Input

第一行一个整数n(2 <= n <= 100000),表示数列中数的个数;

第二行为n个整数pi (1 <= pi <= 1e9)。

Output

输出一个整数,表示操作数量的最小值。如果不存在则输出-1。

Examples

Input

4
24 21 14 10
2
500 500
3
14 5 1
5
1 3 6 9 12

Output

3
0
-1
1

正确解法:

暴力搜索qaq,不够熟悉,再见!

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<string>
 4 #include<cstring>
 5 #include<map>
 6 #include<algorithm>
 7 #include<cmath>
 8 using namespace std; 
 9 int n, a[100100],ans=-1;
10 void dfs(int k, int c, int d)
11 {
12     if (k >= n + 1)
13     {
14         if (ans == -1)
15             ans = c;
16         else ans = min(ans,c);
17         return;
18     }
19     for (int i = -1; i <= 1; i++)
20     {
21         if (a[k] + i - a[k - 1] == d)
22         {
23             a[k] += i;
24             dfs(k + 1, c + abs(i), d);
25             a[k] -= i;
26         }
27     }
28 }
29 int main()
30 {
31     while (cin >> n)
32     {
33         ans = -1;
34         for (int i = 1; i <= n; i++)
35             cin >> a[i];
36         for (int i = -1; i <= 1; i++)
37         {
38             a[1] += i;
39             for (int j = -1; j <= 1; j++)
40             {
41                 a[2] += j;
42                 dfs(3, abs(i) + abs(j), a[2] - a[1]);
43                 a[2] -= j;
44             }
45             a[1] -= i;
46         }
47         cout << ans << endl;
48     }
49     return 0;
50 }
View Code

 

posted @ 2018-11-24 16:21  kaike  阅读(249)  评论(0编辑  收藏  举报