初赛A轮

数列互质

时间限制:6秒

空间限制:524288K

给出一个长度为 n 的数列 { a[1] , a[2] , a[3] , ... , a[n] },以及 m 组询问 ( l[i] , r[i] , k[i])。

求数列下标区间在 [ l[i] , r[i] ] 中有多少数在该区间中的出现次数与 k[i] 互质(最大公约数为1)。

输入描述:
第一行,两个正整数 n , m (1 ≤ n, m ≤ 50000)。
第二行,n 个正整数 a[i] (1 ≤ a[i] ≤ n)描述这个数列。
接下来 m 行,每行三个正整数 l[i] , r[i] , k[i] (1 ≤ l[i] ≤ r[i] ≤ n, 1 ≤ k[i] ≤ n),描述一次询问。
输出描述:
输出 m 行,即每次询问的答案。
输入例子:
10 5
1 1 1 1 1 2 2 2 2 2
4 7 2
4 7 3
4 8 2
4 8 3
3 8 3
输出例子:
0
2
1
1
0

思路:A轮2题。。这题知道是莫队+数据结构,但是没学过莫队,就去学习了一发,然后最后半个小时太心急了,导致没拍完,。。我的T恤啊。。啊。。(另外写了的2题就不补了,心疼,莫队的板子套的是HZWER大佬的,谢谢大佬)
#include<bits/stdc++.h>
using namespace std;

const int N=50004;
int a[N];
set<int >s;
set<int >::iterator it;
int ma[N];
struct node{
    int l,r,x,xx;
    int block;
}e[N];
int c[N];
bool cmp(node p,node q){
    if(p.block==q.block) return p.r<q.r;
    return p.block<q.block;
}
int gcd(int a,int b)
 {
    if(b==0)
        return a;
    return gcd(b,a%b);
 }
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    int size=sqrt(n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&e[i].l,&e[i].r,&e[i].x);
        e[i].xx=i;
        e[i].block=(e[i].l-1)/size+1;
    }
    sort(e+1,e+1+m,cmp);
    int l=1,r=0;
    for(int i=1;i<=m;i++){
        int sum=0;
        while(l>e[i].l){l--;s.insert(a[l]);ma[a[l]]++;}
        while(r<e[i].r){r++;s.insert(a[r]);ma[a[r]]++;}
        while(l<e[i].l){
                ma[a[l]]--;if(ma[a[l]]==0) s.erase(a[l]);l++;}
        while(r>e[i].r) {
                ma[a[r]]--;if(ma[a[r]]==0) s.erase(a[r]);r--;}
        for(it=s.begin();it!=s.end();it++){
            if(gcd(ma[*it],e[i].x)==1){
                sum++;
            }
        }
        c[e[i].xx]=sum;
    }
    for(int i=1;i<=m;i++)printf("%d\n",c[i]);
    return 0;
}
时间: 2024-08-27 09:36:08

初赛A轮的相关文章

【CodeM初赛B轮】F 期望DP

[CodeM初赛B轮]F 题目大意:有n个景点,m条无向边,经过每条边的时间需要的时间是l,在每个景点游览花费的时间是t,游览完每个景点可以获得的满意度是h.你的总时间为k,起初你等概率的选择游览一个景点,然后每次等概率的前往一个相邻的景点游览,当你剩余时间不够游览一个相邻的景点时就结束游览.问所获得的满意度的期望值.(本题强行询问两次~) n<=100,总时间<=500 题解:显然的期望DP啊,不过本题的细节比较多,我这里只说一些细节吧~ 用f[i][j]表示游览完景点i,还剩时间j,所获得

【CodeM初赛B轮】A 贪心

[CodeM初赛B轮]A 题目大意:给你一棵树,起初所有点都是白色的,你每次都能选择一个白点i,将这个点i到根路径上的所有到i的距离<k[i]的点都染成黑色(根和i也算,已经被染成黑色的点还是黑色).问最少需要染多少次才能将所有点都变黑. n<=100000 题解:显然贪心啊,但是我一开始居然写了树剖... 因为叶子节点是一定要染的,所以我们可以将所有点按DFS序排序,从后往前染.记录vis[i],表示之前已经将所有到i的距离<=vis[i]的点染成了黑色:再维护mx[i],表示之前染过

2014第六届华为编程大赛初赛第一轮

/*********************************************************************** 1.投票问题 输入若干候选人,以及投票,格式如下,输出(按输入候选人输入顺序)候选人以及得票,以及 无效票数. Input: addCandidate xx1 addCandidate xx2 addCandidate xx3 addCandidate xx4 addCandidate xx5 addCandidate xx6 vote xx2 vot

CodeM美团点评编程大赛初赛A轮

因为语文太差弃赛,第一个追及问题看不懂我就弃赛了.打进复赛确实挺难的,补一下题,锻炼下就行了. 身体训练 时间限制:1秒 空间限制:32768K 美团外卖的配送员用变速跑的方式进行身体训练.他们训练的方式是:n个人排成一列跑步,前后两人之间相隔 u 米,每个人正常速度均为 v 米/秒.当某个配送员排在最后的时候,他需要以当时自己的最高速度往前跑,直到超过排头的人 u 米,然后降回到原始速度 v 米/秒.每个人最初的最高速度为c[i] 米/秒,每轮衰减d[i] 米/秒,也就是说,如果i是第j个跑的

CodeM美团点评编程大赛初赛B轮 黑白树【DFS深搜+暴力】

[编程题] 黑白树 时间限制:1秒 空间限制:32768K 一棵n个点的有根树,1号点为根,相邻的两个节点之间的距离为1.树上每个节点i对应一个值k[i].每个点都有一个颜色,初始的时候所有点都是白色的. 你需要通过一系列操作使得最终每个点变成黑色.每次操作需要选择一个节点i,i必须是白色的,然后i到根的链上(包括节点i与根)所有与节点i距离小于k[i]的点都会变黑,已经是黑的点保持为黑.问最少使用几次操作能把整棵树变黑. 输入描述: 第一行一个整数n (1 ≤ n ≤ 10^5) 接下来n-1

百度之星初赛B轮 hdu 6114 6118 6119

hdu 6114 思路:就是在max(n,m)中取min(n,m)个,(模板收好 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int MOD=1e9+7; 5 const int N = 2000 + 5; 6 7 int F[N], Finv[N], inv[N]; 8 void init(){ 9 inv[1] = 1; 10 for(int i = 2; i < N

CodeM初赛B轮

做什么啊,我这么菜,应该弃赛的 [编程|1500分] 子串 时间限制:3秒空间限制:32768K 题目描述 给出一个正整数n,我们把1..n在k进制下的表示连起来记为s(n,k),例如s(16,16)=123456789ABCDEF10, s(5,2)=11011100101.现在对于给定的n和字符串t,我们想知道是否存在一个k(2 ≤ k ≤ 16),使得t是s(n,k)的子串. 输入描述: 第一行一个整数n(1 ≤ n ≤ 50,000). 第二行一个字符串t(长度 ≤ 1,000,000)

百度之星初赛A轮 hdu 6108 6112 6113

hdu 6108 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 5 int main(){ 6 int t; 7 cin>>t; 8 while(t--){ 9 ll x; 10 scanf("%I64d",&x); 11 ll ans=0; 12 for(int i=1;i*i<=x;i++){ 13 if((x-1)%i==0) { 14 a

美团2017年CodeM大赛-初赛B轮 黑白树 (树形dp)

大意: 给定树, 初始每个点全为白色, 点$i$有权值$k_i$, 表示选择$i$后, 所有距离$i$小于$k_i$的祖先(包括i)会变为黑色, 求最少选多少个点能使所有点变为黑色. 链上情况的话, 直接从链头开始做一次线性dp就行了, 但是显然不能拓展到树上情况. 正解是从叶子往上贪心划分, 若当前点$x$为白色, 则从$x$子树内选择一个$y$, 满足$k[y]-dis(x,y)$最大, 这个显然可以用树形dp在O(n)时间求出. #include <iostream> #include