牛客練習賽73 D題:離別
題意:
給定一個長度為n的區間 ( n ≤ 300000 ) (n\leq 300000) (n≤300000),區間中每個數 a [ i ] ≤ n a[i]\leq n a[i]≤n,進行下列操作:給定一個區間l,r,問[l,r]的範圍有多少個子區間滿足區間眾數等於k。
題解:
首先我們可以預處理出以i為左區間的滿足條件的r的範圍(這裡用雙指標預處理出mi[i],ma[i]。mi是滿足條件的最小的r,ma是滿足條件的最大的r)。
然後我們把查詢區間按照以l為第一關鍵字降序排列,然後對把l+1到n以每個點滿足條件的範圍進行區間修改。最後區間查詢。
md,線段樹區間查詢在更新操作時忘記下放lazytag了,雙指標那也寫掛了幾次,卡了幾個小時。
AC程式碼:
#include <bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define pb push_back
const ll mod=1e9+7;
using namespace std;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b){ll ret=1; while(b){if(b&1)ret=ret*a%mod;a=a*a%mod;b>>=1;} return ret;}
const int N=3e5+5;
ll n,m,k,cnt[N],a[N],ma[N],mi[N],ans[N],b[4*N],d[4*N];
inline ll read(){
ll num=0,neg=1;char c=getchar();
while(!isdigit(c)){if(c=='-')neg=-1;c=getchar();}
while(isdigit(c)){num=(num<<3)+(num<<1)+c-'0';c=getchar();}
return num*neg;
}
struct node{
int l,r,pos;
bool operator<(const node &x){
return l>x.l;
}
}q[N];
void pushdown(int s,int t,int p){
int mid=(s+t)/2;
d[p<<1]+=(ll)(mid-s+1)*b[p];d[p<<1|1]+=(ll)(t-mid)*b[p];
b[p<<1]+=b[p];b[p<<1|1]+=b[p];
b[p]=0;
}
void pushup(int p){
d[p]=d[p<<1]+d[p<<1|1];
}
void update(int s,int t,int p,int l,int r,int w){
if(l<=s&&t<=r){
d[p]+=(ll)(t-s+1)*(ll)w;
b[p]+=w;
return ;
}
if(b[p]) pushdown(s,t,p);
int mid=(s+t)/2;
if(l<=mid) update(s,mid,p<<1,l,r,w);
if(r>mid) update(mid+1,t,p<<1|1,l,r,w);
pushup(p);
}
ll query(int s,int t,int p,int l,int r){
if(l<=s&&t<=r){
return d[p];
}
if(b[p]) pushdown(s,t,p);
ll ans=0;
int mid=(s+t)/2;
if(l<=mid) ans+=query(s,mid,p<<1,l,r);
if(r>mid) ans+=query(mid+1,t,p<<1|1,l,r);
return ans;
}
int main(){
n=read();m=read();k=read();rep(i,1,n) a[i]=read();
int tmp=0;
for(int l=1,r=1;r<=n;r++){
cnt[a[r]]++;
if(cnt[a[r]]==k) tmp++;
while(cnt[a[r]]==k+1&&l<=r){
ma[l]=r-1;
if(cnt[a[l]]==k) tmp--;
cnt[a[l]]--;
l++;
}
if(r==n){
while(tmp){
ma[l]=r;
if(cnt[a[l]]==k) tmp--;
cnt[a[l]]--;
l++;
}
}
}
memset(cnt,0,sizeof cnt);
for(int l=1,r=1;r<=n;r++){
cnt[a[r]]++;
if(cnt[a[r]]==k){
while(l<=r){
cnt[a[l]]--;
l++;
mi[l-1]=r;
if(cnt[a[r]]!=k) break;
}
}
}
for(int i=1;i<=m;i++){
scanf("%d %d",&q[i].l,&q[i].r);q[i].pos=i;
}
sort(q+1,q+1+m);
int x=n;
for(int i=1;i<=m;i++){
int l=q[i].l,r=q[i].r,pos=q[i].pos;
while(x>=l){
if(mi[x]==0){
x--;continue;
}
update(1,n,1,mi[x],ma[x],1);
x--;
}
ans[pos]=query(1,n,1,l,r);
}
rep(i,1,m) printf("%lld\n",ans[i]);
return 0;
}
/*
*/
相關文章
- 牛客練習賽
- 牛客練習賽60
- 牛客練習賽 26
- 牛客練習賽 71 AC
- 牛客練習賽129 A-數數
- 牛客練習賽26 A 平面【遞推】
- 牛客周賽 Round 36 (小白練習記)
- 牛客SQL練習第21題SQL
- 牛客小白月賽104(A~D)
- 牛客周賽 Round 65(D)
- 牛客小白月賽98 A~D
- 【牛客訓練記錄】牛客周賽 Round 69
- 【牛客訓練記錄】牛客周賽 Round 70
- Mysql 練習(牛客網)MySql
- 牛客練習賽40 B 小A與任務(貪心)
- 牛客小白月賽95 (賽前的練習之我是小菜雞)
- 牛客練習賽14B 區間的連續段
- 牛客練習賽27【C 水圖 dfs求最長路】
- 牛客練習賽26 C 城市規劃【思維+貪心】
- 牛客小白月賽105 題解
- 牛客周賽 Round 66 題解
- 牛客網專項練習(八)——選擇題(錯題&不懂的題)
- 牛客周賽 Round 70 A~G 題解
- 牛客周賽 Round 62 全部題解
- 牛客練習賽74 E CCA的期望(算概率的技巧+floyd處理)
- 牛客周賽48
- 牛客小白月賽88-DE題解
- 牛客小白月賽88 出題覆盤
- 牛客小白月賽105
- 牛客周賽 Round 63
- 牛客周賽 Round 57
- 牛客周賽 Round 56
- 牛客小白月賽97
- 牛客小白月賽88
- 牛客周賽 Round 40
- 牛客小白月賽89
- 牛客周賽 Round 47
- 牛客周賽 Round 1