zoukankan      html  css  js  c++  java
  • CodeForces 221D Little Elephant and Array

    Little Elephant and Array

    Time Limit: 4000ms
    Memory Limit: 262144KB
    This problem will be judged on CodeForces. Original ID: 221D
    64-bit integer IO format: %I64d      Java class name: (Any)

    The Little Elephant loves playing with arrays. He has array a, consisting of n positive integers, indexed from 1 to n. Let's denote the number with index i as ai.

    Additionally the Little Elephant has m queries to the array, each query is characterised by a pair of integers lj and rj (1 ≤ lj ≤ rj ≤ n). For each query lj, rj the Little Elephant has to count, how many numbers x exist, such that number x occurs exactly x times among numbers alj, alj + 1, ..., arj.

    Help the Little Elephant to count the answers to all queries.

     

    Input

    The first line contains two space-separated integers n and m (1 ≤ n, m ≤ 105) — the size of array a and the number of queries to it. The next line contains n space-separated positive integers a1, a2, ..., an (1 ≤ ai ≤ 109). Next m lines contain descriptions of queries, one per line. The j-th of these lines contains the description of the j-th query as two space-separated integers lj and rj (1 ≤ lj ≤ rj ≤ n).

     

    Output

    In m lines print m integers — the answers to the queries. The j-th line should contain the answer to the j-th query.

     

    Sample Input

    Input
    7 2
    3 1 2 2 3 3 7
    1 7
    3 4
    Output
    3
    1

    Source

     
    解题:线段树,甚妙
    改段求点
     1 #include <bits/stdc++.h>
     2 #define A first
     3 #define B second
     4 using namespace std;
     5 typedef pair<int,int> pii;
     6 const int maxn = 100010;
     7 int tree[maxn<<2];
     8 inline void pushdown(int v){
     9     if(tree[v]){
    10         tree[v<<1] += tree[v];
    11         tree[v<<1|1] += tree[v];
    12         tree[v] = 0;
    13     }
    14 }
    15 void update(int L,int R,int lt,int rt,int val,int v){
    16     if(lt <= L && rt >= R){
    17         tree[v] += val;
    18         return;
    19     }
    20     pushdown(v);
    21     int mid = (L + R)>>1;
    22     if(lt <= mid) update(L,mid,lt,rt,val,v<<1);
    23     if(rt > mid) update(mid + 1,R,lt,rt,val,v<<1|1);
    24 }
    25 int query(int L,int R,int pos,int v){
    26     if(L == R) return tree[v];
    27     pushdown(v);
    28     int mid = (L + R)>>1;
    29     if(pos <= mid) return query(L,mid,pos,v<<1);
    30     if(pos > mid) return query(mid + 1,R,pos,v<<1|1);
    31 }
    32 int ans[maxn],a[maxn],cnt[maxn];
    33 vector<int>pos[maxn];
    34 struct QU{
    35     int x,y,id;
    36     bool operator<(const QU &rhs)const{
    37         return y < rhs.y;
    38     }
    39 }q[maxn];
    40 pii pre[maxn];
    41 int main(){
    42     int n,m;
    43     while(~scanf("%d%d",&n,&m)){
    44         memset(tree,0,sizeof tree);
    45         memset(cnt,0,sizeof cnt);
    46         for(int i = 0; i < n; ++i)
    47             scanf("%d",a + i);
    48         for(int i = 0; i < m; ++i){
    49             scanf("%d%d",&q[i].x,&q[i].y);
    50             q[i].id = i;
    51         }
    52         for(int i = 0; i < maxn; ++i) pos[i].clear();
    53         sort(q,q + m);
    54         for(int i = 0, j = 0; i < n; ++i){
    55             if(a[i] <= n){
    56                 pos[a[i]].push_back(i + 1);
    57                 cnt[a[i]]++;
    58                 if(cnt[a[i]] == a[i]){
    59                     pre[a[i]] = pii(1,pos[a[i]][0]);
    60                     update(1,n,pre[a[i]].A,pre[a[i]].B,1,1);
    61                 }else if(cnt[a[i]] > a[i]){
    62                     update(1,n,pre[a[i]].A,pre[a[i]].B,-1,1);
    63                     pre[a[i]] = pii(pre[a[i]].B + 1,pos[a[i]][cnt[a[i]] - a[i]]);
    64                     update(1,n,pre[a[i]].A,pre[a[i]].B,1,1);
    65                 }
    66             }
    67             while(j < m && q[j].y == i + 1){
    68                 ans[q[j].id] = query(1,n,q[j].x,1);
    69                 ++j;
    70             }
    71         }
    72         for(int i = 0; i < m; ++i)
    73             printf("%d
    ",max(0,ans[i]));
    74     }
    75     return 0;
    76 }
    View Code

     改点求段

     1 #include <bits/stdc++.h>
     2 #define A first
     3 #define B second
     4 using namespace std;
     5 typedef pair<int,int> pii;
     6 const int maxn = 100010;
     7 int tree[maxn<<2];
     8 void update(int L,int R,int pos,int val,int v){
     9     if(L == R){
    10         tree[v] += val;
    11         return;
    12     }
    13     int mid = (L + R)>>1;
    14     if(pos <= mid) update(L,mid,pos,val,v<<1);
    15     if(pos > mid) update(mid + 1,R,pos,val,v<<1|1);
    16     tree[v] = tree[v<<1] + tree[v<<1|1];
    17 }
    18 int query(int L,int R,int lt,int rt,int v){
    19     if(lt <= L && rt >= R) return tree[v];
    20     int mid = (L + R)>>1,ret = 0;
    21     if(lt <= mid) ret = query(L,mid,lt,rt,v<<1);
    22     if(rt > mid) ret += query(mid + 1,R,lt,rt,v<<1|1);
    23     return ret;
    24 }
    25 int a[maxn],cnt[maxn],ans[maxn];
    26 vector<int>pos[maxn];
    27 struct QU{
    28     int x,y,id;
    29     bool operator<(const QU &rhs)const{
    30         return y < rhs.y;
    31     }
    32 }q[maxn];
    33 int main(){
    34     int n,m;
    35     while(~scanf("%d%d",&n,&m)){
    36         memset(tree,0,sizeof tree);
    37         memset(cnt,0,sizeof cnt);
    38         for(int i = 0; i < maxn; ++i) pos[i].clear();
    39         for(int i = 0; i < n; ++i)
    40             scanf("%d",a + i);
    41         for(int i = 0; i < m; ++i){
    42             scanf("%d%d",&q[i].x,&q[i].y);
    43             q[i].id = i;
    44         }
    45         sort(q,q + m);
    46         for(int i = 0,j = 0; i < n; ++i){
    47             if(a[i] <= n){
    48                 pos[a[i]].push_back(i + 1);
    49                 ++cnt[a[i]];
    50                 if(cnt[a[i]] >= a[i]) update(1,n,pos[a[i]][cnt[a[i]] - a[i]],1,1);
    51                 if(cnt[a[i]] >= a[i] + 1) update(1,n,pos[a[i]][cnt[a[i]] - a[i] - 1],-2,1);
    52                 if(cnt[a[i]] > a[i] + 1) update(1,n,pos[a[i]][cnt[a[i]] - a[i] - 2],1,1);
    53             }
    54             while(j < m && q[j].y == i + 1){
    55                 ans[q[j].id] = query(1,n,q[j].x,q[j].y,1);
    56                 ++j;
    57             }
    58         }
    59         for(int i = 0; i < m; ++i)
    60             printf("%d
    ",ans[i]);
    61     }
    62     return 0;
    63 }
    View Code
  • 相关阅读:
    2011年需要关注的9大编程语言 狼人:
    微软在华推广Win7拒绝“黑屏” 狼人:
    ifanr访谈:GuruDigger — Web工程师排排坐 狼人:
    10种破除网页设计师障碍的实用方法 狼人:
    英特尔CEO:微软Windows 7是PC更新的催化剂 狼人:
    Windows 7市场份额突破25% XP持续下滑 狼人:
    Office Web Apps中文版正式上线 狼人:
    机器学习实现线性梯度算实现octave
    管理系统数据库sql server 数据库管理
    缓存代码sencha Touch 缓存问题解析
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4887386.html
Copyright © 2011-2022 走看看