zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 41 E. Tufurama (961E)

    【题解】

      第一眼看题飞快地想到一种做法,然后假掉了。

      这道题其实是主席树的模板题来着。但是也有别的水法。

      我们可以发现每个位置的查询区间是[1,min(a[i],i-1)],所以我们可以把查询区间按照右端点排序。开一个权值树状数组记录前i个a[i]的出现情况。我们从1到n按顺序插入a[i],每个位置上都统计min(a[j],j-1)=i的j的答案。

      

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define rg register
     4 #define N 200010
     5 using namespace std;
     6 int n,a[N],b[N],d[N],t[N];
     7 long long ans;
     8 inline int read(){
     9     int k=0,f=1; char c=getchar();
    10     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
    11     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
    12     return k*f;
    13 } 
    14 inline void add(int x){
    15     for(;x<=n;x+=(x&-x)) t[x]++;
    16 }
    17 inline int query(int x){
    18     int ret=0; for(;x>0;x-=(x&-x)) ret+=t[x]; return ret;
    19 }
    20 inline bool cmp(int x,int y){
    21     return d[x]<d[y];
    22 }
    23 int main(){
    24     n=read();
    25     for(rg int i=1;i<=n;i++) a[i]=min(read(),n),b[i]=i,d[i]=min(a[i],i-1);
    26     sort(b+1,b+1+n,cmp);
    27     for(rg int i=1,j=1;i<=n;i++){
    28         add(a[i]);
    29         while(d[b[j]]<i&&j<=n) j++;
    30         while(j<=n&&d[b[j]]==i) ans+=i-query(b[j++]-1);
    31     }
    32     printf("%I64d
    ",ans);
    33     return 0;
    34 }
    View Code
  • 相关阅读:
    课堂检测求一个数的各个位
    猜数字
    登录界面
    课后作业01
    java语言基础问题
    大道至简第一张用java撰写伪代码
    阅读“大道至简”的读后感
    iOS 瀑布流的基本原理
    iOS 生成二维码
    CNContact对通讯录的基本使用(第二篇)
  • 原文地址:https://www.cnblogs.com/DriverLao/p/8728504.html
Copyright © 2011-2022 走看看