• 【HDOJ6701】Make Rounddog Happy(启发式合并)


    题意:给定一个长为n的序列和k,定义子串【L,R】(L<=R)合法当:

    1.max(a[L]..a[R])-(R-L+1)<=k

    2.【L,R】中没有重复的数字

    问合法子串的个数

    n,k,a[i]<=3e5

    思路:对于两个限制分开考虑

    对于限制2,预处理出每个位置只考虑限制2左右最多能扩展到哪里

    对于限制1,将序列以最大值的位置分治,每次只考虑包含最大值的子串

    对于左右两部分其中长度比较小的一部分枚举端点

    因为确定了max,另一端合法的范围也可以求出

    求最大值位置用RMQ预处理

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 typedef unsigned int uint;
      5 typedef unsigned long long ull;
      6 typedef pair<int,int> PII;
      7 typedef pair<ll,ll> Pll;
      8 typedef vector<int> VI;
      9 typedef vector<PII> VII;
     10 //typedef pair<ll,ll>P;
     11 #define N  300010
     12 #define M  2000010
     13 #define fi first
     14 #define se second
     15 #define MP make_pair
     16 #define pb push_back
     17 #define pi acos(-1)
     18 #define mem(a,b) memset(a,b,sizeof(a))
     19 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
     20 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
     21 #define lowbit(x) x&(-x)
     22 #define Rand (rand()*(1<<16)+rand())
     23 #define id(x) ((x)<=B?(x):m-n/(x)+1)
     24 #define ls p<<1
     25 #define rs p<<1|1
     26 
     27 const ll MOD=1e9+7,inv2=(MOD+1)/2;
     28       double eps=1e-6;
     29       int INF=1e9;
     30       int dx[4]={-1,1,0,0};
     31       int dy[4]={0,0,-1,1};
     32 
     33       int f[N<<1][25],a[N],b[N],l0[N],r0[N],n,k;
     34       ll ans;
     35 
     36 int read()
     37 {
     38    int v=0,f=1;
     39    char c=getchar();
     40    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
     41    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
     42    return v*f;
     43 }
     44 
     45 int query(int l,int r)
     46 {
     47     int len=r-l+1;
     48     int t=log2(len);
     49     int x=f[l][t],y=f[r-(1<<t)+1][t];
     50     if(a[x]>a[y]) return x;
     51     return y;
     52 }
     53 
     54 void solve(int l,int r)
     55 {
     56     if(l>r) return;
     57     int mid=query(l,r);
     58     int len=a[mid]-k;
     59     int L,R;
     60     if(mid-l<r-mid)
     61     {
     62         per(i,mid,l)
     63         {
     64             L=max(mid,len+i-1);
     65             R=min(r0[i],r);
     66             if(L<=R) ans+=R-L+1;
     67         }
     68     }
     69      else
     70      {
     71          rep(i,mid,r)
     72          {
     73              L=max(l,l0[i]);
     74              R=min(mid,i-len+1);
     75              if(L<=R) ans+=R-L+1;
     76          }
     77      }
     78     solve(l,mid-1);
     79     solve(mid+1,r);
     80 }
     81 
     82 int main()
     83 {
     84     //freopen("1.in","r",stdin);
     85     //freopen("1.out","w",stdout);
     86     int cas=read();
     87     while(cas--)
     88     {
     89         n=read(),k=read();
     90         rep(i,1,n) a[i]=read();
     91         mem(b,0);
     92         l0[0]=0;
     93         rep(i,1,n)
     94         {
     95             l0[i]=max(l0[i-1],b[a[i]]+1);
     96             b[a[i]]=i;
     97         }
     98         rep(i,1,n) b[a[i]]=n+1;
     99         r0[n+1]=n+1;
    100         per(i,n,1)
    101         {
    102             r0[i]=min(r0[i+1],b[a[i]]-1);
    103             b[a[i]]=i;
    104         }
    105         rep(i,1,n) f[i][0]=i;
    106         for(int i=1;(1<<i)<=n;i++)
    107          rep(j,1,n)
    108          {
    109              int x=f[j][i-1],y=f[j+(1<<(i-1))][i-1];
    110              if(j+(1<<(i-1))>n||a[x]>a[y]) f[j][i]=x;
    111               else f[j][i]=y;
    112          }
    113         ans=0;
    114         solve(1,n);
    115         printf("%I64d
    ",ans);
    116     }
    117 
    118     return 0;
    119 }
  • 相关阅读:
    注册表
    windows.location.href在IE6下停止工作
    LINUX配置IP的三种方式
    InnoSetup 打包代码 检测.netFramework
    SQLiteHelper
    黑马程序员_看视频记笔记_C#编程基础02
    通过注册表来检测是否安装Office
    SQLiteHelper
    TSQL
    IIS下发布关于Excel导入导出时遇到的问题集锦
  • 原文地址:https://www.cnblogs.com/myx12345/p/11722259.html
Copyright © 2020-2023  润新知