link
這題困擾我蠻久的,因為 or
運算不像 xor
或 +
具有反操作。
也就是不能像是 Sliding Window Xor O(1)
滑窗,但是如果拆位的話可能會 TLE。
因此,我們需要一個新的滑窗方法,把原本的陣列先拆成幾塊,然後再滑到某一塊非邊界的點的時候,其 Sliding Window or 就是上個邊界的 or 前墜 or
下個邊界的 or 後墜。
e.g.
原陣列 : 1 2 3 4 5 6 7 8 -> 每三個一塊
前墜or : 1 3 3|4 5 7|7 15
後墜or : 3 3 3|7 7 6|15 8
求 [2,4] 的 or = 到 2 的 後墜or or
的前墜or ->3 or
4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #include<bits/stdc++.h> using namespace std; #define int long long signed main() { ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); int n, m, a, b, c, x; cin>>n>>m>>x>>a>>b>>c; vector<int> arr(n+2, 0), pre(n+2, 0), suf(n+2, 0); arr[1]=x; for(int i=2;i<=n;i++) arr[i]=(a*arr[i-1]+b)%c; for(int i=1, j=n;i<=n;i++, j--) { if(j%m==0) suf[j]=arr[j]; else suf[j]=suf[j+1]|arr[j]; if((i-1)%m==0) pre[i]=arr[i]; else pre[i]=pre[i-1]|arr[i]; } int now=suf[1], temp; for(int l=2, r=m+1;r<=n;l++, r++) { if(l%m==1) temp=suf[l]; else temp=suf[l]|pre[r]; now^=temp; } cout<<now; }
|