zoukankan      html  css  js  c++  java
  • HDU 5172

    超内存了,呃。。。不知道如何优化了。

    首先要判断区间的和是否和1~n的和相等。

    再个,记录下每个数字前一次出现的位置,求这些位置的最大值,如果小于左端点,则表示有这样的一个序列。

    呃~~~第二个条件当时曾有想过,但认为要在O(1)时间内得出不可能,后来才知道,还有ST算法啊。。。。不让熟练啊。。。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #define LL __int64
    
    using namespace std;
    const int MAX=1000002;
    int num[MAX],pre[MAX];
    double sum[MAX];
    int dp[MAX][21];
    
    void ST(int n){ 
        int i, j, k, m;
        k = (int) (log((double)n) / log(2.0)); 
        for(i = 1; i <= n; i++) {
            dp[i][0] = num[i]; 
        }
        for(j = 1; j <= k; j++) { 
            for(i = 1; i + (1 << j) - 1 <= n; i++)   {
                m = i + (1 << (j - 1)); 
                dp[i][j] = max(dp[i][j-1], dp[m][j-1]);
            }
        }
    }
    int rmq(int i, int j) { 
         int k = (int)(log(double(j-i+1)) / log(2.0)), t1; 
         t1 =max(dp[i][k], dp[j - (1<<k) + 1][k]);
         return t1;
    }
    
    int main(){
    	int n,m,tmp,l,r,i; double tsum;
    	while(scanf("%d%d",&n,&m)!=EOF){
    		sum[0]=0;
    		memset(pre,0,sizeof(pre));
    		for(i=1;i<=n;i++){
    			scanf("%d",&tmp);
    			sum[i]=sum[i-1]+tmp;
    			num[i]=pre[tmp];
    			pre[tmp]=i;
    		}
    		ST(n);
    		while(m--){
    			scanf("%d%d",&l,&r);
    			tsum=(r-l+2)*(r-l+1)*1.0/2.0;
    			if(tsum!=sum[r]-sum[l-1]){
    				puts("NO");
    				continue;
    			}
    			if(rmq(l,r)<l){
    				puts("YES");
    			}
    			else puts("NO");
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    设计模式基础:类及类关系的UML表示
    SQL 经典语句
    网络存储
    jstack Dump
    Windows上模拟Linux环境的软件Cygwin
    竞争条件
    Java volatile关键字
    java原子操作
    java死锁小例子
    死锁四个必要条件
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4280097.html
Copyright © 2011-2022 走看看