BestCoder 2nd Anniversary 1005&Hdu 5722 -Jewelry

题意:问有多少个合法区间。

分析:对于[l,r],枚举右区间r,获取合法的l的区间。当增加一个元素Ai,原来合法的区间就会变不合法,要删掉,同时又会新增一个合法的区间,要插入。

例如,当x=2,对于元素 Ai其出现的位置为:1 2 3, 当新增位置4又出现Ai时,那么原来[1+1,2]的区间不合法,删掉。然后区间[2+1,3],插入。

/************************************************
Author        :DarkTong
Created Time  :2016/7/18 22:08:12
File Name     :e.cpp
*************************************************/

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>

#define INF 0x3f3f3f3f
#define esp 1e-9
typedef long long LL;
using namespace std;
const int maxn = 100000 + 100;
map<int, vector<int> > cor;
int a[maxn];
struct Node
{
    int l, r, f;
    LL d;
}st[maxn<<4];
void Build(int x, int L, int R)
{
    st[x].l=L; st[x].r=R; st[x].d=st[x].f=0;
    if(L+1>=R) return;
    int m = (L+R)>>1;
    Build(x<<1, L, m);
    Build(x<<1|1, m, R);
}
void pushup(int x)
{
    if(st[x].f) st[x].d = st[x].r-st[x].l;
    else st[x].d = st[x<<1].d + st[x<<1|1].d;
}
void pushdown(int x)
{
    st[x<<1].f+=st[x].f; st[x<<1|1].f+=st[x].f; st[x].f=0;
}
void Update(int x, int L, int R, int d)
{
    if(L<=st[x].l&&st[x].r<=R)
    {
        st[x].f+=d;
        pushup(x);
        return;
    }
//    pushdown(x);
    int m=(st[x].l+st[x].r)>>1;
    if(L<m) Update(x<<1, L, R, d);
    if(m<R) Update(x<<1|1, L, R, d);
    pushup(x);
}

int main()
{
    int ca, n, x;
    scanf("%d", &ca);
    while(ca--)
    {
        scanf("%d%d", &n, &x);

        LL ans = 0;
        Build(1, 0, n);
        cor.clear();

        for(int i=0;i<n;++i) scanf("%d", &a[i]);
        for(int i=0;i<n;++i)
        {
            if(cor.count(a[i])==0) cor[a[i]].push_back(-1);
            cor[a[i]].push_back(i);
            int si = cor[a[i]].size();
            if(si>=x+1)
            {
                if(si>=x+2) Update(1, cor[a[i]][si-(x+2)]+1, cor[a[i]][si-(x+1)]+1, -1);
                Update(1, cor[a[i]][si-(x+1)]+1, cor[a[i]][si-x]+1, 1);
            }
            ans += st[1].d;
        }
        printf("%lld\n", ans);
    }
    return 0;
}
时间: 2024-10-25 09:14:31

BestCoder 2nd Anniversary 1005&Hdu 5722 -Jewelry的相关文章

BestCoder 2nd Anniversary 1004&amp;Hdu 5721 Palace

题意:给定n个点,对于每次消失一个点,问剩下的点中的最短距离是多少,然后所有最短距离的和. 分析:1.模版题,然而没模版的我码了半天. 2.(1)只要不删掉与最短距离相关的两个点,那么最短距离不变. (2)若与最短距离的点相关,删掉点后,重新算一遍. /************************************************ Author :DarkTong Created Time :2016/7/18 14:01:14 File Name :d.cpp *******

HDU 5720 Wool BestCoder 2nd Anniversary (区间覆盖)

Wool Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 686    Accepted Submission(s): 192 Problem Description At dawn, Venus sets a second task for Psyche. She is to cross a river and fetch gol

HDU 5719 BestCoder 2nd Anniversary Arrange (DP)

Arrange Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 558    Accepted Submission(s): 198 Problem Description Accidentally, Cupid, god of desire has hurt himself with his own dart and fallen

HDU 5721 Palace BestCoder 2nd Anniversary (平面最近点对)

Palace Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 465    Accepted Submission(s): 118 Problem Description The last trial Venus imposes on Psyche is a quest to the underworld. She is to ta

BestCoder 2nd Anniversary

http://acm.hdu.edu.cn/search.php?field=problem&key=BestCoder+2nd+Anniversary&source=1&searchmode=source A 取最小的非零数,再相加 1 // #pragma comment(linker, "/STACK:102c000000,102c000000") 2 #include <iostream> 3 #include <cstdio>

BestCoder 2nd Anniversary的前两题

Oracle Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 79    Accepted Submission(s): 41 Problem Description There is once a king and queen, rulers of an unnamed city, who have three daughters

hdu 5719 BestCoder 2nd Anniversary B Arrange 简单计数问题

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5719 题意:一个数列为1~N的排列,给定mn[1...n]和mx[1...n],问有符合的排列数为多少?如果不存在,输出0: 思路: 有解的几种条件: 1. mn , mx 变化单调: 2. mn,mx 不能同时变化: 3. 一个位置可选的个数>0; 当解存在时,递推出每次可选择的个数,num += mx[i] - mx[i-1] + mn[i-1] - mn[i] - 1; 即可: 坑:开始想成了

BestCoder 2nd Anniversary 1001 Oracle

找到最小的非零数字拆开来相加. 高精度. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 using namespace std; 7 #define LL long long 8 char s[10000005]; 9 int a[10000005],b[10000005]; 10

【HDU5721 BestCoder 2nd AnniversaryD】【平面最近点对 分治写法+KD-tree写法】Palace 平面最近点对

Palace Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 260    Accepted Submission(s): 72 Problem Description The last trial Venus imposes on Psyche is a quest to the underworld. She is to tak