码迷,mamicode.com
首页 > 其他好文 > 详细

洛谷八连测2017R5-whzzt-Confidence

时间:2017-10-28 17:42:20      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:math   show   eof   标记   不同的   tar   gif   alt   相同   

传送门

题目描述

题目难度不一定按照题目顺序递增

请注意本题的空间限制为2333-2500KB!(前三个测试点的空间限制为2500KB)

给定两个长度相同的序列,这两个序列至多有 1 处不同。你的任务是找出这处不同。

输入输出格式

输入格式:

 

第一行包含一个数据组数 TT。每组数据的格式如下:

第一行一个整数 nn 表示序列的长度。

接下来两行表示两个长度均为 nn 的序列 AA 和 BB,保证所有数字均为小于 2^32 的非负整数,这些数字可以看做是随机的。

 

输出格式:

 

输出共 TT 行,每行第一个数 m1 表示不同的数目。接下来 mm 个数表示两个序列中不同的位置。

输入输出样例

输入样例#1: 复制
2
4
2 3 3 3
2 3 6 3
8
9 1 6 2 8 0 7 1
9 1 6 2 0 0 7 1
输出样例#1: 复制
1 3
1 5
技术分享

数据量较大,建议不要使用 cin / cout 输入输出。

为了防止不必要的MLE等情况出现,经过测试,下面的代码使用的空间在2300KB左右浮动。注意头文件所占用的空间也计入程序实际运行所占用的空间内。如在下面的代码中自行使用占用空间更大的数组,不能保证程序能够正常运行。

#include <stdio.h>
using namespace std;

unsigned int a[150005];
int main(){

    return 0;
}


这题可以用异或做

思路是把数字看成一个个的二进制1,然后打上相应的位置的标记,

对于相同的数字异或之后什么的都没有了,而不同的会有位置的标记找到即可

空间复杂度是32int,很不错的方法

 

技术分享
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<map>
 7 #include<set>
 8 #include<queue>
 9 #include<vector>
10 #define INF 0x7f7f7f7f
11 #define pii pair<int,int>
12 #define ll long long
13 #define MAXN 100005
14 using namespace std;
15 int n;
16 ll f[33];
17 ll read(){
18     ll x=0;char ch=getchar();
19     while(ch<0||ch>9){ch=getchar();}
20     while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
21     return x;
22 }
23 int main()
24 {
25     int T;
26     scanf("%d",&T);
27     while(T--){
28         memset(f,0,sizeof(f));
29         ll a=0;
30         scanf("%d",&n);
31         for(int i=1;i<=n;i++){
32             ll t=read();
33             a^=t;
34             int cnt=0;
35             while(t){
36                 if(t&1)f[cnt]^=i;
37                 cnt++;
38                 t>>=1;
39             }
40         }    
41         for(int i=1;i<=n;i++){
42             ll t=read();
43             a^=t;
44             int cnt=0;
45             while(t){
46                 if(t&1)f[cnt]^=i;
47                 cnt++;
48                 t>>=1;
49             }
50         }    
51         if(a){
52             int cnt=0;
53             while(a){
54                 if(a&1){
55                     printf("1 %d\n",f[cnt]);
56                     break;
57                 }
58                 cnt++;
59                 a>>=1;
60             }
61         }
62         else{
63             printf("0\n");
64         }
65     }
66 
67     return 0;
68 }
Code1

 

还可以分别求出∑i*(ai-bi)以及∑i*i*(ai-bi),减掉之后如果等于0,那么肯定是相同的

否则的话肯定是只剩下j*(aj-bj)和j*j*(aj-bj),除掉即可求得j

但是考虑溢出,我们模一下P,然后求出P意义下的逆元即可

技术分享
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<map>
 7 #include<set>
 8 #include<queue>
 9 #include<vector>
10 #define INF 0x7f7f7f7f
11 #define pii pair<int,int>
12 #define ll long long
13 #define uint unsigned int
14 #define P 1000003
15 using namespace std;
16 int ni(ll a){
17     int b=P-2;
18     int ret=1;
19     while(b){
20         if(b&1){
21             ret=1LL*ret*a%P;
22         }
23         a=a*a%P;
24         b>>=1;
25     }
26     return ret;
27 }
28 int n;
29 ll a,b;
30 int main()
31 {
32 //    freopen("data.in","r",stdin);
33     int T;scanf("%d",&T);
34     while(T--){
35         a=0,b=0;
36         int n;scanf("%d",&n);
37         for(int i=1;i<=n;i++){
38             ll t;scanf("%lld",&t);
39             a+=1LL*i*t%P;
40             b+=1LL*i*i%P*t%P;
41         }
42         for(int i=1;i<=n;i++){
43             ll t;scanf("%lld",&t);
44             a-=1LL*i*t%P;if(a<0)a+=P;
45             b-=1LL*i*i%P*t%P;if(b<0)b+=P;
46         }
47         if(!a){
48             printf("0\n");
49         }
50         else{
51             printf("1 %d\n",b*ni(a)%P);
52         }
53     }
54     return 0;
55 }
Code2

 

 

 

洛谷八连测2017R5-whzzt-Confidence

标签:math   show   eof   标记   不同的   tar   gif   alt   相同   

原文地址:http://www.cnblogs.com/w-h-h/p/7747320.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!