• CF961E Fufuruma(分块+树状数组)


    题意:

    找出一个序列里,i<j同时a[i]>j and a[j]>i的对数

    题解:

    问题可以转化为对每个i,找到下标区间在i+1到a[i]内的j,同时a[j]>=i的数的数量,并求和。

    考虑分块,然后对每个块维护一个树状数组。分块做的还是不熟练,比赛的时候数组开小了导致没过。

    分块还是很强,可以做一些线段树做不了的东西。

    这题的正解是可持久化线段树,明天补。

    //一对数成立的标准是
    //i<j
    //a[i]>=j 
    //a[j]>=i
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2e5+100;
    typedef long long ll;
    int lowbit (int x) {
        return x&-x;
    }
    int n;
    int a[maxn];
    int mk[205][maxn];//分块 
    int st[maxn];
    int ed[maxn];
    int pos[maxn];
    int num[maxn];
     
    void up (int p,int x) {
        //修改第i块的位置
        for (int i=x;i<maxn;i+=lowbit(i)) mk[p][i]++; 
    }
    int getsum (int p,int x) {
        int ans=0;
        for (int i=x;i;i-=lowbit(i)) ans+=mk[p][i];
        return ans;
    }
    int main () {
        scanf("%d",&n);
        for (int i=1;i<=n;i++) scanf("%d",a+i),a[i]=min(n,a[i]);
        
        ll ans=0;
        int tt=n/1000;
        for (int i=1;i<=tt;i++) {
            st[i]=(i-1)*1000+1;
            ed[i]=i*1000;
        }
        if (ed[tt]<n) {
            tt++;
            st[tt]=ed[tt-1]+1;
            ed[tt]=n;
        }
        for (int i=1;i<=tt;i++) {
            for (int j=st[i];j<=ed[i];j++) {
                pos[j]=i;
            } 
        } 
        for (int i=1;i<=n;i++) {
            up(pos[i],a[i]);
        }
        for (int i=1;i<=n;i++) {
            //找小于等于a[i]的下标同时a[j]大于等于i的
            //for (int j=i+1;j<=a[i];j++) {
            //    if (a[j]>=i) ans++;
            //}
            int p1=pos[i+1];
            int p2=pos[a[i]];
            if (a[i]<i+1) continue;
            if (p1==p2) {
                for (int j=i+1;j<=a[i];j++) {
                    if (a[j]>=i) ans++;
                }
                continue;
            }
            for (int j=p1;j<=p2;j++) {
                ans+=getsum(j,maxn)-getsum(j,i-1);
            }
            for (int j=a[i]+1;j<=ed[p2];j++) if (a[j]>=i) ans--;
            for (int j=st[p1];j<i+1;j++) if (a[j]>=i) ans--; 
        }
        printf("%lld
    ",ans);
    }
  • 相关阅读:
    如何安装Anaconda和Python
    Vue 语法的一些小问题
    uni-app 常用框架内置方法 更新中 .....
    uni-app 生命周期函数
    Koa2 遇到Method Not Allowed 获取不到返回值
    安装 NodeJ Koa2、3 + 独立插件 cli脚手架 npm cnpm Vue
    vue使用video.js解决m3u8视频播放格式
    Oracle迁移至MySQL
    Spring的15点总结
    全文搜索引擎选 ElasticSearch 还是 Solr?
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/13599193.html
Copyright © 2020-2023  润新知