zoukankan      html  css  js  c++  java
  • codeforces-984D——XOR-pyramid(DP)

    题目传送门

    题目描述:给你一个f函数,这个函数的自变量是一个数列,函数表达式就是题目所给的描述,然后给你一个数列,问你数列中某区间  怎么选取 可以使函数值最大。

    题目思路:  有关区间选取的问题,很容易想到dp,dp[l][r]代表从l到r的区间函数值,然后发现一个神奇的事情,就是:

    dp[l][r]=dp[l][r-1]^dp[l+1][r],这是为什么呢,请允许我用拙劣的画技画一幅通俗易懂的图。


    怎么样,是不是很通俗易懂呀,实现算出了1-3的值,如果要算1-4的值,那就是在后面再加一个圈,红色的线代表因为这个圈新加的内容,最后发现1-4  =   1-3  ^  2-4。

    所以 我们只需要枚举区间长度,就可以算出每个区间的值了。

    看到这里好像以为这道题做完了,只需要算出值,最后查询l-r中所有子区间的最大值就可以了嘛,然而这样会超时,因为n是5000,如果这样做需要2n^2的复杂度,于是亮点来啦。

    用一个ans数组,在dp的过程中就记录答案,也就是说,dp数组记录的是i到j的函数值,而ans数组则记录i到j的最大值,然后读入查询的l和r,o(1)输出答案。(完全离线输出)

    #include<iostream>
    #include<algorithm>
    #include<cstdlib>
    #include<sstream>
    #include<cstring>
    #include<bitset>
    #include<cstdio>
    #include<string>
    #include<deque>
    #include<stack>
    #include<cmath>
    #include<queue>
    #include<set>
    #include<map>
    #define INF 0x3f3f3f3f
    #define CLR(x,y) memset(x,y,sizeof(x))
    #define LC(x) (x<<1)
    #define RC(x) ((x<<1)+1)
    #define MID(x,y) ((x+y)>>1)
    using namespace std;
    typedef long long ll;
    const int maxn=1010;
    char mp[120][120];
    using namespace std;
    typedef long long ll;
    int a[6000];
    int f[6000][6000];
    int ans[6000][6000];
    int main()
    {
    	int n;
    	cin>>n;
    	for(int i=1;i<=n;i++){
    	cin>>a[i];
    	f[i][i]=a[i];//单个值就是本身 
    	ans[i][i]=a[i];
    	}
    	for(int len=2;len<=n;len++){//枚举区间长度 
    		for(int i=1,j=i+len-1 ; j<=n ; i++,j++)
    		{
    			f[i][j]=f[i][j-1]^f[i+1][j];
    			ans[i][j]=max( f[i][j] , max ( ans[i][j-1],ans[i+1][j]) );//预处理 
    		}
    	}
    	int q,l,r;
    	cin>>q;
    	while(q--)
    	{
    		cin>>l>>r;
    		printf("%d
    ",ans[l][r]);
    	}
    }
    D. XOR-pyramid
    time limit per test
    2 seconds
    memory limit per test
    512 megabytes
    input
    standard input
    output
    standard output

    For an array bb of length mm we define the function ff as

    f(b)={b[1]if m=1f(b[1]b[2],b[2]b[3],,b[m1]b[m])otherwise,f(b)={b[1]if m=1f(b[1]⊕b[2],b[2]⊕b[3],…,b[m−1]⊕b[m])otherwise,

    where  is bitwise exclusive OR.

    For example, f(1,2,4,8)=f(12,24,48)=f(3,6,12)=f(36,612)=f(5,10)=f(510)=f(15)=15f(1,2,4,8)=f(1⊕2,2⊕4,4⊕8)=f(3,6,12)=f(3⊕6,6⊕12)=f(5,10)=f(5⊕10)=f(15)=15

    You are given an array aa and a few queries. Each query is represented as two integers ll and rr. The answer is the maximum value of ff on all continuous subsegments of the array al,al+1,,aral,al+1,…,ar.

    Input

    The first line contains a single integer nn (1n50001≤n≤5000) — the length of aa.

    The second line contains nn integers a1,a2,,ana1,a2,…,an (0ai23010≤ai≤230−1) — the elements of the array.

    The third line contains a single integer qq (1q1000001≤q≤100000) — the number of queries.

    Each of the next qq lines contains a query represented as two integers llrr (1lrn1≤l≤r≤n).

    Output

    Print qq lines — the answers for the queries.

    Examples
    input
    Copy
    3
    8 4 1
    2
    2 3
    1 2
    
    output
    Copy
    5
    12
    
    input
    Copy
    6
    1 2 4 8 16 32
    4
    1 6
    2 5
    3 4
    1 2
    
    output
    Copy
    60
    30
    12
    3
    
    Note

    In first sample in both queries the maximum value of the function is reached on the subsegment that is equal to the whole segment.

    In second sample, optimal segment for first query are [3,6][3,6], for second query — [2,5][2,5], for third — [3,4][3,4], for fourth — [1,2][1,2].


  • 相关阅读:
    js最全的十种跨域解决方案
    最常用的~正则表达式相关js函数知识简洁分享【新手推荐】
    HTTP请求 响应状态码
    堆和栈的区别【以java为例潜入分析】
    练习110 编写一个将输入复制到输出的程序,并将其中的制表符替换成\t,把回退符替换成\b,把反斜杠替换成\\,这样可以将制表符和回退符以可见的方式显示出来
    练习111 你准备如何测试单词计数程序? 如果程序中存在某种错误,那么什么样的输入最可能发现这类错误?
    练习114 编写一个程序, 打印输入中各个字符出现频度的直方图。
    The C programming language Test
    进驻首日..感谢师父的教导
    练习112:编写一个程序,以每行一个单词的形式打印其输入。
  • 原文地址:https://www.cnblogs.com/mountaink/p/9536718.html
Copyright © 2011-2022 走看看