美团codem 数列互质 - 莫队
题目描述
输入格式
输出格式
样例
数据范围与提示
思路分析 : 莫队基本题目,暴力维护的区间的元素有区间内不同元素的出现次数,同时再记录一下出现不同的次数有多少次,记录一下某个区间不同次数的种类,类似链表
复杂度 :某个区间不同元素的次数种类最多有 根号n 种,总的复杂度就是 n*sqrt(n)*log(n)
写的时候有个地方写错了,就是分块的排序的地方... 一直TLE
代码示例 :
using namespace std;
#define ll long long
const int maxn = 5e4+5;
const int mod = 1e9+7;
const double eps = 1e-9;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
inline int read()
{
int ret=0,c,f=1;
for(c=getchar(); !(isdigit(c)||c=='-'); c=getchar());
if(c=='-') f=-1,c=getchar();
for(; isdigit(c); c=getchar()) ret=ret*10+c-'0';
if(f<0) ret=-ret;
return ret;
}
int n, m;
struct node
{
int zu;
int l, r, k, id;
bool operator< (const node &v)const{
if (zu == v.zu) return r < v.r;
return l < v.l;
}
}a[maxn];
int pre[maxn], cnt[maxn];
int num[maxn], time2[maxn<<2];
int all;
bool pt[maxn<<2];
int ans[maxn];
int gcd(int a, int b){
return b==0?a:gcd(b, a%b);
}
inline void remove(int x){
cnt[x]--;
num[cnt[x]]++, num[cnt[x]+1]--;
time2[all++] = cnt[x];
}
inline void add(int x){
cnt[x]++;
num[cnt[x]]++, num[cnt[x]-1]--;
time2[all++] = cnt[x];
}
int main() {
int l, r, k;
cin >> n >> m;
int unit = sqrt(n);
for(int i = 1; i <= n; i++) pre[i] = read();
for(int i = 1; i <= m; i++){
l = read(), r = read(), k = read();
//scanf("%d%d%d", &l, &r, &k);
int f = (l-1)/unit+1;
a[i] = {f, l, r, k, i};
}
sort(a+1, a+1+m);
l = a[1].l, r = a[1].l-1;
all = 1; int sum = 0;
for(int i = 1; i <= m; i++){
while(l < a[i].l) remove(pre[l++]);
while(r > a[i].r) remove(pre[r--]);
while(l > a[i].l) add(pre[--l]);
while(r < a[i].r) add(pre[++r]);
k = 1; sum = 0;
for(int j = 1; j < all; j++){
if (!pt[time2[j]] && num[time2[j]] > 0){
if (gcd(time2[j], a[i].k) == 1) {
sum += num[time2[j]];
}
time2[k++] = time2[j];
pt[time2[j]] = true;
}
}
all = k;
ans[a[i].id] = sum;
for(int j = 1; j < k; j++) pt[time2[j]] = false;
}
for(int i = 1; i <= m; i++) printf("%d\n", ans[i]);
return 0;
}
东北日出西边雨 道是无情却有情

浙公网安备 33010602011771号