Official

E - Many Operations Editorial by kyopro_friends


操作はbitごとに独立であるため、bitごとに分けて考えて良いです。

操作 ii{0,1}\{0,1\} から {0,1}\{0,1\} への関数 fif_i とみなします。関数 ff を組 (f(0),f(1))(f(0),f(1)) で表現しながら、合成関数 fifi1f1f_i\circ f_{i-1}\circ\ldots \circ f_1 を順に計算することで、この問題を O(NlogA)O(N\log A) で解くことができます。

実装例(C++)

Copy
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define bit(x,i)(((x)>>(i))&1)
  4. int main(){
  5. int n,c;
  6. cin >> n >> c;
  7. vector<pair<int,int>>op(n);
  8. for(int i=0;i<n;i++)cin >> op[i].first >> op[i].second;
  9. vector<int>ans(n);
  10. for(int k=0;k<30;k++){
  11. array<int,2>func={0,1};
  12. int crr=bit(c,k);
  13. for(int i=0;i<n;i++){
  14. array<int,2>f;
  15. int x=bit(op[i].second,k);
  16. if(op[i].first==1)f={0&x,1&x};
  17. if(op[i].first==2)f={0|x,1|x};
  18. if(op[i].first==3)f={0^x,1^x};
  19. func={f[func[0]],f[func[1]]};
  20. crr=func[crr];
  21. ans[i]|=crr<<k;
  22. }
  23. }
  24. for(int i=0;i<n;i++)cout << ans[i] << endl;
  25. }
#include<bits/stdc++.h>
using namespace std;
#define bit(x,i)(((x)>>(i))&1)

int main(){
	int n,c;
	cin >> n >> c;
	vector<pair<int,int>>op(n);
	for(int i=0;i<n;i++)cin >> op[i].first >> op[i].second;

	vector<int>ans(n);
	for(int k=0;k<30;k++){
		array<int,2>func={0,1};
		int crr=bit(c,k);
		for(int i=0;i<n;i++){
			array<int,2>f;
			int x=bit(op[i].second,k);
			if(op[i].first==1)f={0&x,1&x};
			if(op[i].first==2)f={0|x,1|x};
			if(op[i].first==3)f={0^x,1^x};
			func={f[func[0]],f[func[1]]};
			crr=func[crr];
			ans[i]|=crr<<k;
		}
	}

	for(int i=0;i<n;i++)cout << ans[i] << endl;
}

類題 『Odd Operator』(MojaCoder)

posted:
last update:



2025-04-05 (Sat)
22:07:12 +00:00