zoukankan      html  css  js  c++  java
  • 【2019多校】Make Rounddog Happy(分治)

    Rounddog always has an array a1,a2,,ana1,a2,⋯,an in his right pocket, satisfying 1ain1≤ai≤n .

    A subarray is a non-empty subsegment of the original array. Rounddog defines a good subarray as a subsegment al,al+1,,aral,al+1,⋯,ar that all elements in it are different and max(al,al+1,,ar)(rl+1)kmax(al,al+1,…,ar)−(r−l+1)≤k .

    Rounddog is not happy today. As his best friend, you want to find all good subarrays of aa to make him happy. In this case, please calculate the total number of good subarrays of aa .

    InputThe input contains several test cases, and the first line contains a single integer T (1T20)T (1≤T≤20) , the number of test cases.

    The first line of each test case contains two integers n (1n300000)n (1≤n≤300000) and k (1k300000)k (1≤k≤300000) .

    The second line contains nn integers, the ii -th of which is ai (1ain)ai (1≤ai≤n) .

    It is guaranteed that the sum of nn over all test cases never exceeds 10000001000000 .
    OutputOne integer for each test case, representing the number of subarrays Rounddog likes.

    Sample Input

    2
    5 3
    2 3 2 2 5
    10 4
    1 5 4 3 6 2 10 8 4 5

    Sample Output

    7
    31
    SOLUTION:
    很容易想到考虑每一个数作为最大值的情况,然后处理出他所能想两边扩展的区间
    但是向两边的很好搞,但是必须跨区间,然后就自闭了
    后来知道分治可以很好的搞这个问题
    题解:https://www.cnblogs.com/Dillonh/p/11390927.html
    启发式的所有东西都是玄学的复杂度。。。。。qwq

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=1000010;
    int a[maxn],st[maxn][21],lg[maxn],K,N; ll ans;
    int A[maxn],B[maxn],vis[maxn];
    int get(int L,int R)
    {
        int k=lg[R-L+1];
        return a[st[L][k]]>=a[st[R-(1<<k)+1][k]]?st[L][k]:st[R-(1<<k)+1][k];
    }
    void solve(int L,int R)
    {
        if(L>R) return ;
        int pos=get(L,R);
        if(pos-L<R-pos){
            rep(i,L,pos){
                int t=a[pos]-K,lR=i+t-1;
                int fcy=min(R,B[i]);
                lR=max(lR,pos);
                if(lR>fcy) continue;
                ans+=fcy-lR+1;
            }
        }
        else {
            rep(i,pos,R){
                int t=a[pos]-K,rL=i-t+1;
                int fcy=max(L,A[i]);
                rL=min(rL,pos);
                if(rL<fcy) continue;
                ans+=rL-fcy+1;
            }
        }
        solve(L,pos-1); solve(pos+1,R);
    }
    int main()
    {
        int T;
        lg[0]=-1; rep(i,1,maxn-1) lg[i]=lg[i>>1]+1;
        scanf("%d",&T);
        while(T--){
            scanf("%d%d",&N,&K); ans=0;
            rep(i,1,N) scanf("%d",&a[i]);
            rep(i,1,N) st[i][0]=i;
            rep(i,1,20) {
                rep(j,1,N+1-(1<<i))
                 st[j][i]=a[st[j][i-1]]>=a[st[j+(1<<(i-1))][i-1]]?st[j][i-1]:st[j+(1<<(i-1))][i-1];
            }
        
            rep(i,1,N) vis[i]=0; A[1]=1; vis[a[1]]=1;
            rep(i,2,N){
                 if(vis[a[i]])  A[i]=max(A[i-1],vis[a[i]]+1);
                 else A[i]=A[i-1];
                 vis[a[i]]=i;
            }
            rep(i,1,N) vis[i]=0; B[N]=N; vis[a[N]]=N;
            for(int i=N-1;i>=1;i--){
                if(vis[a[i]]) B[i]=min(B[i+1],vis[a[i]]-1);
                else B[i]=B[i+1];
                vis[a[i]]=i;
            }
            solve(1,N);
            printf("%lld
    ",ans);
        }
        return 0;
    } 
    

      












  • 相关阅读:
    绑定方法、非绑定方法与静态方法
    封装、隐藏和property装饰器
    自己动手写中文分词解析器完整教程,并对出现的问题进行探讨和解决(附完整c#代码和相关dll文件、txt文件下载)
    SASS -- 基本认识
    网易新闻页面信息抓取 -- htmlagilitypack搭配scrapysharp
    爬虫技术(四)-- 简单爬虫抓取示例(附c#代码)
    c# -- 读取文件夹中的所有文件(备忘)
    爬虫技术(五)-- 模拟简单浏览器(附c#代码)
    爬虫技术(六)-- 使用HtmlAgilityPack获取页面链接(附c#代码及插件下载)
    关于引用mshtml的问题
  • 原文地址:https://www.cnblogs.com/zhangbuang/p/11604831.html
Copyright © 2011-2022 走看看