【Codeforces 983B】XOR-pyramid | 思维、dp

太菜了太菜了,日常被1800吊锤

题目大意:

给出 f ( b ) f(b) f(b)的递归定义:
【Codeforces 983B】XOR-pyramid | 思维、dp
【Codeforces 983B】XOR-pyramid | 思维、dp
然后进行 Q Q Q次询问,每次询问区间 [ l , r ] [l,r] [l,r]内,所有子区间 [ x , y ] [x,y] [x,y]的 f ( a [ x : y ] ) f(a[x:y]) f(a[x:y])的最大值

题目思路:

以为很简单的题…(确实简单)

被卡了,主要原因是忽略了题目给出的定义。

第一眼看到这个题可能没什么思路,但仔细理一下题目的定义会发现:

x 1 ⊕ x 2 ⊕ x 3 ⊕ x 4 ⊕ x 5 x_1⊕ x_2⊕ x_3⊕ x_4 ⊕x_5 x1​⊕x2​⊕x3​⊕x4​⊕x5​
x 1 ⊕ x 2 ∣ x 2 ⊕ x 3 ∣ x 4 ⊕ x 5 x_1⊕ x_2 | x_2⊕ x_3 | x_4⊕x_5 x1​⊕x2​∣x2​⊕x3​∣x4​⊕x5​
x 1 ⊕ x 2 ⊕ x 2 ⊕ x 3 ∣ x 2 ⊕ x 3 ⊕ x 4 ⊕ x 5 x_1⊕ x_2⊕ x_2⊕x_3 |x_2⊕x_3 ⊕x_4⊕x_5 x1​⊕x2​⊕x2​⊕x3​∣x2​⊕x3​⊕x4​⊕x5​
x 1 ⊕ x 2 ⊕ x 2 ⊕ x 3 ⊕ x 2 ⊕ x 3 ⊕ x 4 ⊕ x 5 x_1⊕ x_2⊕ x_2⊕x_3⊕x_2⊕x_3 ⊕x_4⊕x_5 x1​⊕x2​⊕x2​⊕x3​⊕x2​⊕x3​⊕x4​⊕x5​

显然规律:

d p [ i ] [ k ] = d p [ i − 1 ] [ k ] ⊕ d p [ i − 1 ] [ k + 1 ] dp[i][k] = dp[i-1][k] ⊕dp[i-1][k+1] dp[i][k]=dp[i−1][k]⊕dp[i−1][k+1]

也就是说第 i i i层的第 j j j个位置的值为 d p [ i ] [ j ] dp[i][j] dp[i][j]

设 f [ l ] [ r ] f[l][r] f[l][r]代表区间 [ l , r ] [l,r] [l,r]的异或值,写一下规律就会发现,每个区间到最后的值都对应着 d p dp dp数组某层的某个节点。

很明显推出来:

f [ l ] [ r ] = d p [ r − l + 1 ] [ l ] f[l][r] = dp[r-l+1][l] f[l][r]=dp[r−l+1][l]

然后所有的区间的异或值也就得出来了,得出来后,只需要将区间扩充一下就好了。

经典规律题不会了.

/*** keep hungry and calm CoolGuang!  ***/
//#pragma GCC optimize(3)
#include <bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<string.h>
#include<iostream>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const ll INF= 1e18+7;
const ll maxn = 1e6+700;
const int M = 1e6+8;
const ll mod= 1000000007;
const double eps = 1e-9;
const double PI = acos(-1);
template<typename T>inline void read(T &a){char c=getchar();T x=0,f=1;while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}a=f*x;}
ll n,m,p;
int dp[5005][5005],f[5005][5005];
int a[maxn];
int main(){
  read(n);
  for(int i=1;i<=n;i++) read(a[i]);
  for(int k=1;k<=n;k++) dp[1][k] = a[k];
  for(int i=2;i<=n;i++)
    for(int k=1;k<=n-i+1;k++)
      dp[i][k] = dp[i-1][k]^dp[i-1][k+1];
  for(int i=1;i<=n;i++) f[i][i] = a[i];
  for(int len=1;len<=n-1;len++){
    for(int s=1;s+len<=n;s++){
      int t = s+len;
      f[s][t] = max(f[s+1][t],f[s][t-1]);
      f[s][t] = max(f[s][t],dp[len+1][t-len]);
    }
  }
  read(m);
  for(int i=1;i<=m;i++){
    int x,y;read(x);read(y);
    if(x>y) swap(x,y);
    di(f[x][y]);
  }
  return 0;
}
上一篇:CF1515H


下一篇:基础位运算符