Codeforces-984 D-XOR-pyramid-思考


リンクを解く:
https://www.lucien.ink/archives/212/
テーマリンク:
http://codeforces.com/contest/984/problem/D
タイトル:
For an array b b of length m we define the function f as
f(b){b[1],f(b[1]⊕b[2],b[2]⊕b[3],…,b[m−1]_;b[m]if m=1 otherswise(1)(1)f(b){b[1],i f  m=1 f(b[1]⊕b[2],b[2]_;b[3],…,b[m−1]_;b[m]o t h e e
where_;is bitwise exclusive OR.
For example,f(1,2,4,8)=f(1⊕2,2⊕4,4⊕8)=f(3,6,12)=f(3,6,6)=f(5,10)=f(5⊕10)=f(5)=f(15=f=f(15=1=f=1,=1=f=1,=f=1,8853=f=f=f=2,===f(3,88888888888888888853)= f=f=f=f======f=f===================f=f=f=f=====f=f=========イ6,6⊕12)=f(5,10)=f(5⊕10)=f(15)=15
You are given an array a and a few queries.Each query is represented as two integers l and r.The answer is the maximvalue of f on all continuous subsegments of the array,l+1,a.l+a.a.l.a.r.a.a.r.r.a.r.r.a.r.r.a.a.r.r.r.a.r.r.r.r.r.r.r.r.r.r.r.r
Input
The first line contains a single integer n (1≦n≦5000)n  (1≦n≦5000)—the length of a.
The second line contains nn integers a 1,a 2,…,an (0≦ai≦230−1)a 1,a 2,…,a n  (0≦a i≦2 30−1)—the elemens of the array.
The third line contains a single integer q (1≦q≦100 000)q  (1≦q≦100  000)—the number of queries.
Each of the next q linea query represented as two integers l,r (1≦l≦r≦n)l,r  (1≦l≦r≦n).
Output
Print q q lines-the answers for the queries.
件名:
関数f(b)f(b)f(b)を定義します。bは配列に対応しています。作用方式は題意を参照してください。nの長さのシーケンスbを与えます。その後、qに問い合わせてみます。各問い合わせに対して、l rをあげます。[l,r][l,r]この区内のすべてのサブストリングのfの最大値はfですか?
考え方:
この問題を見始めた時はまだ20分残っていましたが、子供はもう長い間考えていました。そして、とても大切な性質を発見しました。
f[l]f[r]を[l,r]の区間で関数fを定義した結果、次のようになります。
f[l][r]{b[l],f[l][r−1]_;f[l+1][r]if l=rotherwise(2)(2)f[l]、[r]{b[l],i f  l=r f[l][r−1]f[l+1][r]o t h e r w i s e
  そこで、私達はこの性質によってO(n 2)O(n 2)のすべての区間のf fを前処理して、同時に解答をオフラインして、O(1)O(1)の答えを出せばいいです。
実装:
#include 
int f[5007][5007], ans[5007][5007], n, q, l, r, i;
int main() {
    for (scanf("%d", &n), i = 1; i <= n; i++) scanf("%d", f[i] + i), ans[i][i] = f[i][i];
    for (int len = 2; len <= n; len++)
        for (l = 1, r; (r = l + len - 1) <= n; l++) {
            f[l][r] = f[l][r - 1] ^ f[l + 1][r];
            ans[l][r] = std::max(f[l][r], std::max(ans[l][r - 1], ans[l + 1][r]));
        }
    for (scanf("%d", &q), i = 0; i < q; i++) {
        scanf("%d%d", &l, &r);
        printf("%d
"
, ans[l][r]); } return 0; }