~是按位取反運算符
這里先說一下二進制在內存的存儲:二進制數在內存中以補碼的形式存儲
另外,正數的原碼、補碼和反碼都相同
負數的反碼與原碼符號位相同,數值為取反;補碼是在反碼的基礎上加1
比如:
~9的計算步驟:
轉二進制:0 1001
計算補碼:0 1001
按位取反:1 0110
轉為原碼:1 0110
按位取反:1 1001 反碼
末位加一:1 1010 補碼
符號位為1是負數,即-10
規律:~x=-(x+1);
因此,t=~9(1001)並不能輸出6(0110),而是-10;
牛客網暑假訓練第七場A題:
鏈接:https://www.nowcoder.com/acm/contest/145/A
來源:牛客網
Minimum Cost Perfect Matching
時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 262144K,其他語言524288K
Special Judge, 64bit IO Format: %lld
空間限制:C/C++ 262144K,其他語言524288K
Special Judge, 64bit IO Format: %lld
題目描述
You have a complete bipartite graph where each part contains exactly n nodes, numbered from 0 to n - 1 inclusive.
The weight of the edge connecting two vertices with numbers x and y is
(bitwise AND).
Your task is to find a minimum cost perfect matching of the graph, i.e. each vertex on the left side matches with exactly one vertex on the right side and vice versa. The cost of a matching is the sum of cost of the edges in the matching.
denotes the bitwise AND operator. If you're not familiar with it, see {https://en.wikipedia.org/wiki/Bitwise_operation#AND}.
The weight of the edge connecting two vertices with numbers x and y is

Your task is to find a minimum cost perfect matching of the graph, i.e. each vertex on the left side matches with exactly one vertex on the right side and vice versa. The cost of a matching is the sum of cost of the edges in the matching.

輸入描述:
The input contains a single integer n (1 ≤ n ≤ 5 * 10
5
).
輸出描述:
Output n space-separated integers, where the i-th integer denotes p
i
(0 ≤ p
i
≤ n - 1, the number of the vertex in the right part that is matched with the vertex numbered i in the left part. All p
i
should be distinct.
Your answer is correct if and only if it is a perfect matching of the graph with minimal cost. If there are multiple solutions, you may output any of them.
示例1
代碼:
#include<bits/stdc++.h>
using namespace std; typedef long long ll; typedef unsigned long long ull; #define mod 1000000007
const int N=5e+5; int a[N]; int main() { ios_base::sync_with_stdio(0); cin.tie(0); int n; cin>>n; memset(a,-1,sizeof(a)); for(int i=n-1;i>=0;i--) { int t=~i,k=0;//此時t是以補碼輸出的,是負數
/*********************** 9 1001 取反 0110 & 1111 得: 0110 */cout<<t; while(1<<k<i)k++; cout<<(1<<k)-1; t=t&((1<<k)-1);cout<<t<<endl; if(a[i]==-1) a[i]=t,a[t]=i; } for(int i=0;i<n;i++) cout<<a[i]<<" "; cout<<endl; return 0; }