Hướng dẫn giải của Bedao Mini Contest 26 - Mảng OR


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Xét một vị trí ~r~ cố định, xét các hậu tố ~f_i~ ~=~ ~a_i~ ~|~ ~a_{i + 1}~ ~|~ ~\cdots~ ~|~ ~a_r~. Ta sẽ xem xét sự thay đổi của dãy hậu tố ~f~ khi thêm phần tử ~r + 1~.

Dễ thấy ~f_1 \ge f_2 \ge \cdots \ge f_r~. Giá trị của hậu tố tăng khi độ dài tăng. Cụ thể các bit ~1~ sẽ giữ nguyên và các bit ~0~ có thể thay đổi thành bit ~1~. Do đó chỉ có tối đa ~k~ giá trị phân biệt của dãy hậu tố, ~k~ là số lượng bit. Nếu ~f_{i - 1} = f_{i}~, ta chỉ cần giữ lại ~1~ giá trị ~f_i~. Khi đó ta có chiến thuật làm như sau:

  • Duyệt qua từng phần tử của dãy ~a~ từ trái qua phải và dùng một mảng ~m~ (hoặc set) để lưu các giá trị phân biệt của dãy hậu tố. Kích thước của mảng sẽ luôn nhỏ hơn hoặc bằng ~k~ (như phân tích trên);

  • Khi duyệt từ vị trí ~i - 1~ sang ~i~, thay đổi mảng ~m =~ ~m_1~, ~m_2~, ~\cdots~, ~m_t~ thành ~m =~ ~a_i~, ~m_1 | a_i~, ~m_2 | a_i~, ~\cdots~, ~m_t | a_i~;

  • Xoá bỏ các giá trị trùng lặp trong mảng ~m~ và thêm các giá trị này vào mảng kết quả.

#include<bits/stdc++.h>
#define fr first
#define sc second
#define P pair<int,int>
#define m_p make_pair
#define pb push_back
#define lowbit(x) (x&(-x))
#define int long long
typedef long long ll;
using namespace std;
set<int> ans,now;
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int n;cin>>n;
    for(int i=0;i<n;i++){
        int x;cin>>x;
        now.insert(0);
        set<int> nw;
        for(set<int>::iterator it=now.begin();it!=now.end();it++){
            int y=(*it);
            nw.insert((x|y));
            ans.insert((x|y));
        }
        now=nw;
    }
    cout<<ans.size()<<endl;
    return 0;
}

Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.