【HDOJ6602】Longest Subarray(线段树,vector)

题意:给定一个长为n的序列,第i个数a[i]都是一个[1,c]中的整数

如果一段序列[l,r]中出现过的数字出现次数都>=K则称其为好的序列

求最长的好的序列的长度

n,k,c,a[i]<=1e5

思路 :考虑固定右端点,对于每种数字来说合法的左端点都是两段

将对于每种数字来说合法的左端的位置都+1,则和为c的位置都是合法的,显然取最小的左端点

右端点右移的时候推一下左端点如何移动,用一个vector存每种数字出现的位置,往前k个就直接下标减k

  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  100010
 12 #define M  200010
 13 #define fi first
 14 #define se second
 15 #define MP make_pair
 16 #define pi acos(-1)
 17 #define mem(a,b) memset(a,b,sizeof(a))
 18 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
 19 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
 20 #define lowbit(x) x&(-x)
 21 #define Rand (rand()*(1<<16)+rand())
 22 #define id(x) ((x)<=B?(x):m-n/(x)+1)
 23 #define ls p<<1
 24 #define rs p<<1|1
 25 
 26 const ll MOD=1e9+7,inv2=(MOD+1)/2;
 27       double eps=1e-4;
 28       int INF=1<<30;
 29       ll inf=5e13;
 30       int dx[4]={-1,1,0,0};
 31       int dy[4]={0,0,-1,1};
 32 
 33 int mx[N<<2],tag[N<<2],pos[N<<2],n,C,k;
 34 VI c[N];
 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 void pushup(int p)
 46 {
 47     if(mx[ls]>=mx[rs])
 48     {
 49         mx[p]=mx[ls];
 50         pos[p]=pos[ls];
 51     }
 52      else
 53      {
 54          mx[p]=mx[rs];
 55          pos[p]=pos[rs];
 56      }
 57 }
 58 
 59 void pushdown(int p)
 60 {
 61     if(tag[p]!=0)
 62     {
 63         tag[ls]+=tag[p];
 64         tag[rs]+=tag[p];
 65         mx[ls]+=tag[p];
 66         mx[rs]+=tag[p];
 67         tag[p]=0;
 68     }
 69 }
 70 
 71 void build(int l,int r,int p)
 72 {
 73     mx[p]=tag[p]=0;
 74     pos[p]=l;
 75     if(l==r) return;
 76     int mid=(l+r)>>1;
 77     build(l,mid,ls);
 78     build(mid+1,r,rs);
 79 }
 80 
 81 void update(int l,int r,int x,int y,int v,int p)
 82 {
 83     if(l>r) return;
 84     if(x>y) return;
 85     if(x<=l&&r<=y)
 86     {
 87         mx[p]+=v;
 88         tag[p]+=v;
 89         return;
 90     }
 91     pushdown(p);
 92     int mid=(l+r)>>1;
 93     if(x<=mid) update(l,mid,x,y,v,ls);
 94     if(y>mid) update(mid+1,r,x,y,v,rs);
 95     pushup(p);
 96 }
 97 
 98 int query(int l,int r,int x,int y,int p)
 99 {
100     if(l>r) return 0;
101     if(x>y) return 0;
102     if(mx[p]!=C) return 0;
103     if(x<=l&&r<=y) return pos[p];
104     pushdown(p);
105     int mid=(l+r)>>1;
106     int res=query(l,mid,x,y,ls);
107     if(res) return res;
108     return query(mid+1,r,x,y,rs);
109 }
110 int main()
111 {
112     while(scanf("%d%d%d",&n,&C,&k)!=EOF)
113     {
114         build(1,n,1);
115         rep(i,1,C)
116         {
117             c[i].clear();
118             c[i].push_back(0);
119         }
120         int ans=0;
121         rep(i,1,n)
122         {
123             //printf("i=%d\n",i);
124             int x=read();
125             update(1,n,i,i,C-1,1);
126             update(1,n,c[x].back()+1,i-1,-1,1);
127             c[x].push_back(i);
128             int now=(int)c[x].size()-k-1;
129             if(now>=0) update(1,n,c[x][now]+1,c[x][now+1],1,1);
130             int j=query(1,n,1,i,1);
131             if(j) ans=max(ans,i-j+1);
132         }
133         printf("%d\n",ans);
134     }
135 
136 
137     return 0;
138 }

 

posted on 2019-09-25 16:17  myx12345  阅读(181)  评论(0编辑  收藏  举报

导航