Codeforces 549F Yura and Developers

probelm

题意

给定一个序列和一个mod值,定义[l,r]合法当lr的所有元素和减去其中的最大值的结果能够整除mod。问共有多少区间合法。

思路

一开始想的分治。对于一个[l,r]我们可以把这之中最大的求出来,然后以这个数作为分界,把这个区间分成两部分,对于分布在两个区间中的答案,我们可以通过lowerbound和upperbunder在O(log(n))的时间下求出,然后递归求解。然而对于这题,这种做法的下界会达到O(n2)。所以这样做不行。。

  • 看了题解,题解说可以直接枚举那个最大值,然后把满足的区间找出来然后求出来。豁然开朗。这样我们只需要把原数组进行排序,并记录每个数的左右界。从最小的开始,在计算答案的同时去更新这个左右界。这样可以在O(nlog(n))的复杂度下求出答案。
  • 一道不错的题。希望以后能够坚持把每次做的比赛的题目补完。

AC代码

/*************************************************************************
    > File Name: pf.cpp
    > Author: znl1087
    > Mail: [email protected]
    > Created Time: 四  6/11 16:36:14 2015
 ************************************************************************/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#define LL long long
using namespace std;
int n,k;
LL s[300005];
vector<int> f[1000005];
LL num[300005];
int pre[300005],nxt[300005];
LL ask(int l,int r,LL in){
    return upper_bound(f[in].begin(),f[in].end(),r)-lower_bound(f[in].begin(),f[in].end(),l);
}
LL cal(int m){
    int l = pre[m]+1,r = nxt[m]-1;
    LL maxn = num[m];
    LL ans = 0;
    if( r - m < m - l){
        for(int i=m+1;i<=r;i++)
            ans+=(ask(l-1,m-1,(s[i]-maxn%k+k)%k));
        ans+=(ask(l-1,m-2,(s[m]-maxn%k+k)%k));
    }else{
        for(int i=l;i<m;i++)
            ans+=(ask(m,r,(s[i-1]+maxn)%k));
        ans+=(ask(m+1,r,(s[m-1]+maxn)%k));
    }
    pre[nxt[m]] = pre[m];
    nxt[pre[m]] = nxt[m];
    return ans;
}
int ord[300005];
int cmp(int a,int b){
    return num[a]<num[b];
}
int main(){
    cin>>n>>k;
    s[0] = 0;
    for(int i=1;i<=n;i++){
        cin>>num[i],s[i] = (s[i-1]+num[i])%k,ord[i] = i;
        pre[i] = i-1;
        nxt[i] = i+1;
    }
    nxt[0] = 1;
    nxt[n] = n+1;
    pre[n+1] = n;
    for(int i=0;i<=n;i++)f[s[i]].push_back(i);
    sort(ord+1,ord+n+1,cmp);
    LL ans = 0;
    for(int i=1;i<=n;i++){
        int pos = ord[i];
        ans+=cal(pos);
    }
    cout<<ans<<endl;
    return 0;
}
时间: 2024-10-05 23:58:14

Codeforces 549F Yura and Developers的相关文章

●CodeForces 549F Yura and Developers

题链: http://codeforces.com/problemset/problem/549/F题解: 分治,链表. 考虑对于一个区间[L,R],其最大值在p位置, 那么答案的贡献就可以分为3部分: 1.[L,p-1]中合法的区间 2.[p+1,R]中合法的区间 3.[L,R]中经过p的合法区间. 前两个因为是相同子问题,可以递归解决. 考虑如何求出3.的答案. 令S[i]表示$\sum_{k=1}^{i}A[i]$(即前缀和) 显然对于一组(l,r)表示的区间[l,r], 当且仅当满足L<

codeforces #549 Looksery Cup 部分题解

掉Rating快乐~~ A.Face Detection 题目大意:给定一个n?m的矩阵,求有多少2?2的子矩形满足单词"face"的每个字母在矩形中恰好出现一次 签到题 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 55 using namespace std; int n,m,ans; char map[M

Looksery Cup 2015 Editorial

下面是题解,做的不好.下一步的目标是rating涨到 1800,没打过几次cf A. Face Detection Author: Monyura One should iterate through each 2x2 square and check if it is possible to rearrange letters in such way they they form the word "face". It could be done i.e. by sorting al

Codeforces Round #339 (Div. 2) B. Gena&#39;s Code

B. Gena's Code It's the year 4527 and the tanks game that we all know and love still exists. There also exists Great Gena's code, written in 2016. The problem this code solves is: given the number of tanks that go into the battle from each country, f

CodeForces 567B Berland National Library

Description Berland National Library has recently been built in the capital of Berland. In addition, in the library you can take any of the collected works of Berland leaders, the library has a reading room. Today was the pilot launch of an automated

Codeforces Round #Pi (Div. 2) (ABCD题解)

比赛链接:http://codeforces.com/contest/567 听说Round #Pi的意思是Round #314... A. Lineland Mail time limit per test:3 seconds memory limit per test:256 megabytes All cities of Lineland are located on the Ox coordinate axis. Thus, each city is associated with it

【codeforces 718E】E. Matvey&#39;s Birthday

题目大意&链接: http://codeforces.com/problemset/problem/718/E 给一个长为n(n<=100 000)的只包含‘a’~‘h’8个字符的字符串s.两个位置i,j(i!=j)存在一条边,当且仅当|i-j|==1或s[i]==s[j].求这个无向图的直径,以及直径数量. 题解:  命题1:任意位置之间距离不会大于15. 证明:对于任意两个位置i,j之间,其所经过每种字符不会超过2个(因为相同字符会连边),所以i,j经过节点至多为16,也就意味着边数至多

Codeforces 124A - The number of positions

题目链接:http://codeforces.com/problemset/problem/124/A Petr stands in line of n people, but he doesn't know exactly which position he occupies. He can say that there are no less than a people standing in front of him and no more than b people standing b

Codeforces 841D Leha and another game about graph - 差分

Leha plays a computer game, where is on each level is given a connected graph with n vertices and m edges. Graph can contain multiple edges, but can not contain self loops. Each vertex has an integer di, which can be equal to 0, 1 or  - 1. To pass th