atcoder beginer 347 (abc347) D E 題解

congmingyige發表於2024-04-12

D

就是二進位制下,哪些位置有重合(兩個1),哪些位置沒有重合(1個1,1個0),剩下的都是0。

xor的結果<2^60,就是小於60位(二進位制下)。注意要有要求兩個數需要是2^60,於是要有大小的判斷,因為有的a,b會2^60,但是按照題目要求,這個情況不行。

比如xor的結果,60位都是1,然後a、b各有60個1,那麼需要有30個1重合,然後a、b的最高位數是90。

比如xor的結果,是1後面59個0,a、b各有30、31個1,那麼有30個1重合,然後a、b的最高位數是61(這個是比較特殊的樣例,a的位數+b的位數-xor的位數<60但,xor的位數卻大於60)。

另外,除錯,也可以用assert(rx<(1ll<<60));的方式。

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <cstdbool>
  6 #include <string>
  7 #include <algorithm>
  8 #include <iostream>
  9 #include <sstream>
 10 #include <ctime>
 11 #include <stack>
 12 #include <vector>
 13 #include <queue>
 14 #include <set>
 15 #include <map>
 16 #include <array>
 17 #include <assert.h>
 18 using namespace std;
 19 #define LL long long
 20 #define ULL unsigned long long
 21 
 22 const LL mod_1=1e9+7;
 23 const LL mod_2=998244353;
 24 
 25 const double eps_1=1e-5;
 26 const double eps_2=1e-10;
 27 
 28 const int maxn=500;
 29 
 30 
 31 LL w[maxn],x[maxn],y[maxn];
 32 
 33 int main()
 34 {
 35     LL a,b,c,len=0,cnt_one=0,cnt_loop,rx,ry;
 36     LL i;
 37 
 38     cin>>a>>b>>c;
 39 
 40     memset(w,0,sizeof(w));
 41 
 42     while (c)
 43     {
 44         w[len]=c&1;
 45         c=c>>1;
 46         cnt_one+=w[len];
 47         len++;
 48     }
 49 
 50     if (abs(a-b)>cnt_one || a+b<cnt_one || (a+b-cnt_one)%2==1)  // || (a+b-cnt_one>60)
 51     {
 52         cout << "-1";
 53         return 0;
 54     }
 55 
 56     //cout << "-2";
 57     //return 0;
 58 
 59     cnt_loop=(a+b-cnt_one)/2;
 60     a-=cnt_loop;
 61     b-=cnt_loop;
 62 
 63     memset(x,0,sizeof(x));
 64     memset(y,0,sizeof(y));
 65 
 66     for (i=0;i<len;i++)
 67         if (w[i]==1)
 68         {
 69             if (a>0)
 70             {
 71                 x[i]=1;
 72                 a--;
 73             }
 74             else if (b>0)
 75             {
 76                 y[i]=1;
 77                 b--;
 78             }
 79         }
 80 
 81     for (i=0;i<maxn;i++)
 82         if (cnt_loop>0 && x[i]==0 && y[i]==0)
 83         {
 84             x[i]=1;
 85             y[i]=1;
 86             cnt_loop--;
 87         }
 88 
 89     rx=0;
 90     for (i=maxn-1;i>=0;i--)
 91         rx=(rx<<1ll)|x[i];
 92     ry=0;
 93     for (i=maxn-1;i>=0;i--)
 94         ry=(ry<<1ll)|y[i];
 95 
 96 
 97     //assert(rx<(1ll<<60));
 98     //assert(ry<(1ll<<60));
 99 
100     for (i=maxn-1;i>=60;i--)
101         if (x[i]==1 || y[i]==1)
102         {
103             cout << "-1";
104             return 0;
105         }
106 
107     //cout << (1ll<<60) <<endl;   ///要打括號,否則輸出160
108 
109     cout<<rx<<" "<<ry<<endl;
110     return 0;
111 }
112 /*
113 
114 3 0 7
115 
116 59 0 1152921504606846975
117 60 0 1152921504606846975
118 
119 1 0 1152921504606846976
120 
121 
122 0 0 1152921504606846976
123 0 60 1152921504606846976
124 60 0 1152921504606846976
125 0 1 1152921504606846976
126 59 0 1152921504606846975
127 
128 0 2 3
129 0 3 88
130 0 4 88
131 */

E

題目轉化為一個數,是從什麼時候開始出現,什麼時候結束,然後可能有若干個迴圈。

否則,解法,可能是不是如可持久化這種奇怪的東西……因為一次只變一個數字。

那麼多人透過這道題,是應該想一下原因。

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <cstdbool>
 6 #include <string>
 7 #include <algorithm>
 8 #include <iostream>
 9 #include <sstream>
10 #include <ctime>
11 #include <stack>
12 #include <vector>
13 #include <queue>
14 #include <set>
15 #include <map>
16 #include <array>
17 using namespace std;
18 #define LL long long
19 #define ULL unsigned long long
20 
21 const LL mod_1=1e9+7;
22 const LL mod_2=998244353;
23 
24 const double eps_1=1e-5;
25 const double eps_2=1e-10;
26 
27 const int maxn=2e5+10;
28 
29 int f[maxn], cnt[maxn];
30 LL total_cnt[maxn], result[maxn];
31 
32 vector<pair<int,int> > vec[maxn];
33 
34 
35 int main()
36 {
37     int n,q,d,ind, number=0,i;
38     scanf("%d%d",&n,&q);
39 
40     for (ind=1;ind<=q;ind++)
41     {
42         scanf("%d",&d);
43 
44         if (f[d]==0)
45         {
46             f[d]=ind;
47             number++;
48             cnt[ind]=number;
49         }
50         else
51         {
52             vec[d].push_back( make_pair(f[d],ind-1) );
53             f[d]=0;
54             number--;
55             cnt[ind]=number;
56         }
57     }
58 
59     for (i=1;i<=n;i++)
60         if (f[i]!=0)
61             vec[i].push_back( make_pair(f[i], q));
62 
63     total_cnt[0]=0;
64     for (i=1;i<=q;i++)
65         total_cnt[i]=total_cnt[i-1]+cnt[i];
66     for (i=1;i<=n;i++)
67     {
68         for (auto pai:vec[i])
69         {
70             result[i] += total_cnt[pai.second] - total_cnt[pai.first-1];
71         }
72     }
73 
74     for (i=1;i<=n;i++)
75     {
76         cout<<result[i];
77         if (i==n)
78             cout<<endl;
79         else
80             cout<<" ";
81     }
82 
83     return 0;
84 }

相關文章