zoukankan      html  css  js  c++  java
  • HH的项链

    这道题在线不好做,但是可以离线......

    就是把所有的询问都读进来,按照r排序,

    扫描原序列,并且记录这种颜色上一次出现的位置,

    这样每次add(i,1) add(last[val[i]],-1)  (last[val[i]]!=0)

    如果是一个询问的左端点,就利用树状数组的前缀和进行统计

    这道题不好做的地方就在于一个颜色重复出现多次不好用前缀和计算,而一个同样的颜色如果在右边出现了,左边的可以不计,这就是这个解法的开始,

    很巧妙啊......

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 const int maxn=1000119;
     8 int n,m;
     9 int val[maxn],last[maxn],c[maxn];
    10 int ans[maxn];
    11 struct Node{
    12   int l,r,id,ans;
    13 }node[maxn];
    14 bool cmp(Node a,Node b){
    15   return a.r<b.r;
    16 }
    17 bool cm(Node a,Node b){
    18   return a.id<b.id;
    19 }
    20 int lowbit(int x){
    21   return x&(-x);
    22 }
    23 int sum(int x){
    24   int ret=0;
    25   for(int i=x;i>0;i-=lowbit(i)) ret+=c[i];
    26   return ret; 
    27 }
    28 void add(int pos,int val){
    29   for(int i=pos;i<=n;i+=lowbit(i)) c[i]+=val;
    30 }
    31 int main(){
    32   cin>>n;
    33   for(int i=1;i<=n;i++) cin>>val[i];
    34   cin>>m;
    35   for(int i=1;i<=m;i++){
    36     int l,r;cin>>l>>r;
    37     node[i].l=l;node[i].r=r;node[i].id=i;
    38   }
    39   sort(node+1,node+m+1,cmp);
    40   int j=1;
    41   for(int i=1;i<=n;i++){
    42       if(last[val[i]]!=0) add(last[val[i]],-1);
    43     add(i,1);
    44     while(i==node[j].r){
    45       node[j].ans=sum(node[j].r)-sum(node[j].l-1);
    46       j++;
    47     }
    48     last[val[i]]=i;
    49   }
    50   sort(node+1,node+m+1,cm);
    51   for(int i=1;i<=m;i++) cout<<node[i].ans<<endl;
    52 } 
  • 相关阅读:
    力扣算法:组合总和IV
    力扣算法:组合总和III
    逻辑回归(Logistic Regression)学习笔记
    力扣算法:组合总和II
    力扣算法:组合总和
    寒假作业(五)
    寒假作业(四)
    寒假作业(三)
    寒假作业(二)
    寒假学习(一)
  • 原文地址:https://www.cnblogs.com/lcan/p/9901204.html
Copyright © 2011-2022 走看看