原生安卓、谷歌pixel系列去除網路WiFi紅叉號
阿新 • • 發佈:2022-03-14
題面
在實現程式自動分析的過程中,常常需要判定一些約束條件是否能被同時滿足。
考慮一個約束滿足問題的簡化版本:假設 \(x_1,x_2,x_3,\cdots\) 代表程式中出現的變數,給定 \(n\) 個形如 \(x_i=x_j\) 或 \(x_i\neq x_j\) 的變數相等/不等的約束條件,請判定是否可以分別為每一個變數賦予恰當的值,使得上述所有約束條件同時被滿足。例如,一個問題中的約束條件為:\(x_1=x_2,x_2=x_3,x_3=x_4,x_4\neq x_1\),這些約束條件顯然是不可能同時被滿足的,因此這個問題應判定為不可被滿足。
現在給出一些約束滿足問題,請分別對它們進行判定。
【資料範圍】
思路
可以用並查集維護。
如果相等,那麼合併。如果不等,檢查是否在一個集合中,如果在就是 NO
, 否則就是 YES
。
至於值域問題,可以考慮以下方案:
- 離散化
- 使用對映資料結構(如
std::map
,std::unordered_map
,__gnu_pbds::gp_hash_table
等)。
這裡使用第二種。經過實驗,只有 std::unordered_map
能過。其他都是 \(90\) 分(開了 \(\text{O2}\) )。
#include <bits/stdc++.h> //#include <bits/extc++.h> using namespace std; //using namespace __gnu_pbds; const int SIZE = 1e6+5; int t,T; struct query{ int i,j,e; } querys[SIZE]; unordered_map<int,int> fa; namespace IO{ const int SIZE=1<<21; static char ibuf[SIZE],obuf[SIZE],*iS,*iT,*oS=obuf,*oT=oS+SIZE-1; int qr; char qu[55],c; bool f; #define getchar() (IO::iS==IO::iT?(IO::iT=(IO::iS=IO::ibuf)+fread(IO::ibuf,1,IO::SIZE,stdin),(IO::iS==IO::iT?EOF:*IO::iS++)):*IO::iS++) #define putchar(x) *IO::oS++=x,IO::oS==IO::oT?flush():0 #define flush() fwrite(IO::obuf,1,IO::oS-IO::obuf,stdout),IO::oS=IO::obuf #define puts(x) IO::Puts(x) template<typename T> inline void read(T&x){ for(f=1,c=getchar();c<48||c>57;c=getchar())f^=c=='-'; for(x=0;c<=57&&c>=48;c=getchar()) x=(x<<1)+(x<<3)+(c&15); x=f?x:-x; } template<typename T> inline void write(T x){ if(!x) putchar(48); if(x<0) putchar('-'),x=-x; while(x) qu[++qr]=x%10^48,x/=10; while(qr) putchar(qu[qr--]); } inline void Puts(const char*s){ for(int i=0;s[i];i++) putchar(s[i]); putchar('\n'); } struct Flusher_{~Flusher_(){flush();}}io_flusher_; } using IO::read; using IO::write; int find(int x){ if(fa[x]==x)return x; else return fa[x]=find(fa[x]); } void merge(int x,int y){ fa[find(x)]=find(y); } bool same(int x,int y){ return find(x)==find(y); } void solve(){ read(t); for(int i=1;i<=t;i++){ query &nq=querys[i]; read(nq.i);read(nq.j);read(nq.e); } for(int i=1;i<=t;i++){ query &nq=querys[i]; fa[nq.i]=nq.i; fa[nq.j]=nq.j; } for(int i=1;i<=t;i++){ query &nq=querys[i]; if(nq.e==1){ merge(nq.i,nq.j); } } for(int i=1;i<=t;i++){ query &nq=querys[i]; if(nq.e==0){ if(same(nq.i,nq.j)){ putchar('N');putchar('O');putchar('\n'); return; } } } putchar('Y');putchar('E');putchar('S');putchar('\n'); } int main(){ read(T); while(T--){ solve(); } return 0; }
建議使用 C++14 (GCC 9) O2
。