sloj bzoj2821. L的鞋子
题目描述
L是壕,他非常喜欢鞋子,他专门在他的别墅中修建了一个鞋柜,鞋柜是呈线性的,为了好找鞋子,他把他的鞋子分成了c种。虽然L没有小学毕业,但是对数字非常偏爱,他很忌讳奇数,因为他觉得不吉利(壕都是这样的)。他想知道对于一个区间[l,r]中,有多少种鞋子恰好出现正偶数次。
输入格式
第一行3个整数,n,c,m
第二行n个数,每个数Ai在[1,c],表示第i双鞋子的样式
接下来m行,每行2个整数l,r,表示询问[l,r]的答案
输出格式
m行,回答答案
样例
数据规模与约定
共有10组测试数据
1-4组n,m=500,2000,5000,10000,c=1000
5-7组n,m=20000,30000,40000,c=10000
8-10组n,m=50000,80000,100000,c=100000
数据保证随机生成
非常明显的一道莫队,区间都给你给出来了,这看不出来?
这个奇偶数非常好判断,只需要开一个数组,挪移的时候注意加减就行了
上一篇算法学习中提到的add()与del()函数于此读者可自行体会
#include<bits/stdc++.h> using namespace std; struct node{ int l,r,belong,id; bool operator<(const node &b){ return (belong!=b.belong)?belong<b.belong:r<b.r; } }q[100010]; int n,c,m,k,a[100010],ans[100010],cnt[100010]; void add(int &num,int pos){ cnt[a[pos]]++; if(cnt[a[pos]]==1) return; if(cnt[a[pos]]%2==0) num--; else num++; } void del(int &num,int pos){ cnt[a[pos]]--; if(!cnt[a[pos]]) return; if(cnt[a[pos]]%2==0) num--; else num++; } int main(){ scanf("%d%d%d",&n,&c,&m); k = sqrt(n); for(int i = 1;i<=n;i++) scanf("%d",&a[i]); for(int i = 1;i<=m;i++){ scanf("%d%d",&q[i].l,&q[i].r); q[i].id = i,q[i].belong = (q[i].l-1)/k+1; } sort(q+1,q+m+1); int l = 1,r = 0,num = 0; for(int i = 1;i<=m;i++){ while(l<q[i].l) del(num,l++); while(l>q[i].l) add(num,--l); while(r<q[i].r) add(num,++r); while(r>q[i].r) del(num,r--); ans[q[i].id] = num; } for(int i = 1;i<=m;i++) printf("%d\n",-ans[i]); return 0; }
梦与现实间挣扎着,所求为何
你可以借走我的文章,但你借不走我的智慧 虽然我是傻逼本文来自博客园,作者:cztq,转载请注明原文链接:https://www.cnblogs.com/cztq/p/17044180.html