P2709 小B的询问 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
思路:最最模板的一集.
//#pragma GCC optimize(2) o2优化
//#pragma GCC optimize(3,"Ofast","inline") o3优化
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
int n,m,k,B;
int arr[50004],p[50004];
typedef struct Q{
int l,r,idx;
}Q;
Q q[50004];
//bool cmp(Q a,Q b){ 普通分块排序
// if(a.l/B!=b.l/B) return a.l<b.l;
// return a.r<b.r;
//}
bool cmp(Q a,Q b){ 玄学奇偶性排序
if (p[a.l] ^ p[b.l]) return a.l/B < b.l/B ;
else{
if (p[a.l] & 1) return a.r < b.r;
else return a.r > b.r;
}
}
int l=0,r=0,res=0,cnt[50004],ans[50004];
P2709 小B的询问
https://www.luogu.com.cn/problem/P2709
void solve(){
cin>>n>>m>>k;
B=sqrt(n);
for(int i=1;i<=n;i++) cin>>arr[i];
for(int i=1;i<=m;i++) cin>>q[i].l>>q[i].r,q[i].idx=i,p[q[i].l]=q[i].l/B,p[q[i].r]=q[i].r/B;
sort(q+1,q+m+1,cmp);
l=q[1].l+1,r=q[1].l;
for(int i=1;i<=m;i++){
while(l>q[i].l) {
--l;
int num=arr[l];
if(num<=k) {
res-=cnt[num]*cnt[num];
cnt[num]++;
res+=cnt[num]*cnt[num];
}
}
while(r<q[i].r) {
++r;
int num=arr[r];
if(num<=k) {
res-=cnt[num]*cnt[num];
cnt[num]++;
res+=cnt[num]*cnt[num];
}
}
while(l<q[i].l) {
int num=arr[l];
if(num<=k){
res-=cnt[num]*cnt[num];
cnt[num]--;
res+=cnt[num]*cnt[num];
}
l++;
}
while(r>q[i].r) {
int num=arr[r];
if(num<=k){
res-=cnt[num]*cnt[num];
cnt[num]--;
res+=cnt[num]*cnt[num];
}
r--;
}
ans[q[i].idx]=res;
}
for(int i=1;i<=m;i++) cout<<ans[i]<<endl;
}
signed main() {
ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
int t=1;
//cin>>t;
while(t--){
solve();
}
return 0;
}
P1903 [国家集训队] 数颜色 / 维护队列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
思路:带修莫队,多了操作和回退的操作.
//#pragma GCC optimize(2) o2优化
//#pragma GCC optimize(3,"Ofast","inline") o3优化
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
int n,m,B;
int arr[200005],p[200005];
int ans[200005],cnt[1000006];
int idxR=0,idxQ=0;
typedef struct r{
int p,c;
}r;
r R[200005];
typedef struct q{
int l,r,tim,id;
}q;
bool cmp(q a,q b){ 奇偶性排序
if(p[a.l] ^ p[b.l]) return a.l<b.l;
else if(p[a.r] ^ p[b.r]) return a.r<b.r; p[a.r] != p[b.r] 不是a.r!=b.r
else return a.tim<b.tim; 时间排序
}
q Q[200005];
带修莫队
P1903 [国家集训队] 数颜色 / 维护队列
https://www.luogu.com.cn/problem/P1903
void solve(){
cin>>n>>m;
B=pow(n,0.666);
for(int i=1;i<=n;i++) cin>>arr[i];
for(int i=1;i<=m;i++){
char op; cin>>op;
int l,r; cin>>l>>r;
if(op=='Q') {
Q[++idxQ].l=l,Q[idxQ].r=r,Q[idxQ].tim=idxR,Q[idxQ].id=idxQ;
p[Q[idxQ].l]=ceil(1.0*Q[idxQ].l/B),p[Q[idxQ].r]=ceil(1.0*Q[idxQ].r/B);
}
else R[++idxR].p=l,R[idxR].c=r;
}
sort(Q+1,Q+idxQ+1,cmp);
int l=Q[1].l+1,r=Q[1].l,t=0,res=0;
for(int i=1;i<=idxQ;i++){
while(l>Q[i].l){ 左扩展
--l;
cnt[arr[l]]++;
if(cnt[arr[l]]==1) res++;
}
while(r<Q[i].r){ 右扩展
++r;
cnt[arr[r]]++;
if(cnt[arr[r]]==1) res++;
}
while(l<Q[i].l){ 左删除
cnt[arr[l]]--;
if(cnt[arr[l]]==0) res--;
++l;
}
while(r>Q[i].r){ 右删除
cnt[arr[r]]--;
if(cnt[arr[r]]==0) res--;
--r;
}
while(t<Q[i].tim){ 进行操作
int p0=R[++t].p;
if(p0>=Q[i].l&&p0<=Q[i].r){ 要在范围内才更新!!
cnt[arr[p0]]--;
if(cnt[arr[p0]]==0) res--;
cnt[R[t].c]++;
if(cnt[R[t].c]==1) res++;
}
swap(arr[p0],R[t].c);
}
while(t>Q[i].tim){ 回退操作
int p0=R[t].p;
if(p0>=Q[i].l&&p0<=Q[i].r){ 要在范围内才更新!!
cnt[arr[p0]]--;
if(cnt[arr[p0]]==0) res--;
cnt[R[t].c]++;
if(cnt[R[t].c]==1) res++;
}
swap(arr[p0],R[t].c);
t--;
}
ans[Q[i].id]=res;
}
for(int i=1;i<=idxQ;i++) cout<<ans[i]<<endl;
}
signed main() {
ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
int t=1;
//cin>>t;
while(t--){
solve();
}
return 0;
}
Problem - H - Codeforces-Round974-Div3
思路:最普通的莫队板子.没想到出现在div3的最后一题。用随机数异或哈希也能过.
int n,m,k,B;
int arr[250004],p[250004];
typedef struct Q{
int l,r,idx;
}Q;
Q q[250004];
//bool cmp(Q a,Q b){ 普通分块排序
// if(a.l/B!=b.l/B) return a.l<b.l;
// return a.r<b.r;
//}
bool cmp(Q a,Q b){ 玄学奇偶性排序
if (p[a.l] ^ p[b.l]) return a.l/B < b.l/B ;
else{
if (p[a.l] & 1) return a.r < b.r;
else return a.r > b.r;
}
}
int l=0,r=0,cnt[1000006],ans[250004];
P2709 小B的询问
https://www.luogu.com.cn/problem/P2709
void solve(){
cin>>n>>m;
B=sqrt(n);
for(int i=1;i<=n;i++) cin>>arr[i],cnt[arr[i]]=0;
for(int i=1;i<=m;i++) cin>>q[i].l>>q[i].r,q[i].idx=i,p[q[i].l]=q[i].l/B,p[q[i].r]=q[i].r/B;
sort(q+1,q+m+1,cmp);
l=q[1].l+1,r=q[1].l;
int cnt1=0;//
for(int i=1;i<=m;i++){
while(l>q[i].l) {
--l;
cnt[arr[l]]^=1;
if(cnt[arr[l]]==1) cnt1++;
else cnt1--;
}
while(r<q[i].r) {
++r;
cnt[arr[r]]^=1;
if(cnt[arr[r]]==1) cnt1++;
else cnt1--;
}
while(l<q[i].l) {
cnt[arr[l]]^=1;
if(cnt[arr[l]]==1) cnt1++;
else cnt1--;
l++;
}
while(r>q[i].r) {
cnt[arr[r]]^=1;
if(cnt[arr[r]]==1) cnt1++;
else cnt1--;
r--;
}
ans[q[i].idx]=(cnt1==0);
}
for(int i=1;i<=m;i++){
if(ans[i]==1) cout<<"YES\n";
else cout<<"NO\n";
}
}
F-小苯的回文询问_牛客周赛 Round 38 (nowcoder.com)
思路:最普通的板子,得o(1)维护变动.
int n,m,B;
int arr[100005],p[200005];
typedef struct Q{
int l,r,idx;
}Q;
Q q[200005];
bool cmp(Q a,Q b){ 玄学奇偶性排序
if (p[a.l] ^ p[b.l]) return a.l/B < b.l/B ;
else{
if (p[a.l] & 1) return a.r < b.r;
else return a.r > b.r;
}
}
int l=0,r=0,ans[200005];
void solve(){ //牛客周赛Round38 //F 又是莫队
cin>>n>>m;
B=sqrt(n);
unordered_map<int,int> ha;
int num=0;
for(int i=1;i<=n;i++) {
cin>>arr[i];
if(ha[arr[i]]==0) ha[arr[i]]=++num; 离散化
arr[i]=ha[arr[i]];
}
for(int i=1;i<=m;i++) cin>>q[i].l>>q[i].r,q[i].idx=i,p[q[i].l]=q[i].l/B,p[q[i].r]=q[i].r/B;
sort(q+1,q+m+1,cmp);
l=q[1].l+1,r=q[1].l;
int cnt[200005];
int cntNex=0,cnt2=0,cnt3=0;
for(int i=1;i<=m;i++){
while(l>q[i].l){ //扩张
--l;
cnt[arr[l]]++;
if(cnt[arr[l]]==2) cnt2++;
if(cnt[arr[l]]==3) cnt3++;
if(arr[l]==arr[l+1]) cntNex++;
}
while(r<q[i].r){ //扩张
++r;
cnt[arr[r]]++;
if(cnt[arr[r]]==2) cnt2++;
if(cnt[arr[r]]==3) cnt3++;
if(arr[r]==arr[r-1]) cntNex++;
}
while(l<q[i].l){ //收缩
cnt[arr[l]]--;
if(cnt[arr[l]]==1) cnt2--;
if(cnt[arr[l]]==2) cnt3--;
if(arr[l]==arr[l+1]) cntNex--;
l++;
}
while(r>q[i].r){ //收缩
cnt[arr[r]]--;
if(cnt[arr[r]]==1) cnt2--;
if(cnt[arr[r]]==2) cnt3--;
if(arr[r]==arr[r-1]) cntNex--;
r--;
}
if(cnt3||cnt2>cntNex) ans[q[i].idx]=1;
}
for(int i=1;i<=m;i++) ans[i]?cout<<"YES"<<endl:cout<<"NO"<<endl;
}