zoukankan      html  css  js  c++  java
  • CF961E Tufurama 树状数组

    E. Tufurama

    One day Polycarp decided to rewatch his absolute favourite episode of well-known TV series "Tufurama". He was pretty surprised when he got results only for season 7 episode 3 with his search query of "Watch Tufurama season 3 episode 7 online full hd free". This got Polycarp confused — what if he decides to rewatch the entire series someday and won't be able to find the right episodes to watch? Polycarp now wants to count the number of times he will be forced to search for an episode using some different method.

    TV series have n seasons (numbered 1 through n), the i-th season has ai episodes (numbered 1 through ai). Polycarp thinks that if for some pair of integers x and y (x < y) exist both season x episode y and season y episode x then one of these search queries will include the wrong results. Help Polycarp to calculate the number of such pairs!

    Input

    The first line contains one integer n (1  ≤ n  ≤  2·10^5) — the number of seasons.

    The second line contains n integers separated by space a1, a2, ..., an (1 ≤ ai ≤ 10^9) — number of episodes in each season.

    Output

    Print one integer — the number of pairs x and y (x < y) such that there exist both season x episode y and season y episode x.

    题意:

    有一部电视剧有n季,每一季有ai集。定义二元组(i,j):存在第i季有第j集。求(i,j)与(j,i)同时合法(i<j)的对数。

    真实题意就是:求<i,j>对数,使得a[i]≥j,a[j]≥i并且(i<j)


    BIT做法

    像很多其他题一样,对于这样的、关于元素大小关系之间的限制的题目,先排个序总是能够解决个一维限制掉去的。

    我们使用一个结构体node x,x.i表示季数;x.a表示该季的集数。首先对x.a排序。那么就变成这个样子:

    p[].a(j)  3  5  1  2
    p[].i(i)  1  2  3  4
      |
      |
    p[].a(j)  1  2  3  4 (取min之后)
    p[].i(i)  3  4  1  2

    先考虑每次的统计,那么只要ans+=query(a[i])就可以了。意思就是说ans加上1..a[i]季的贡献(其中每一季的贡献要么是0要么是1,但是由于之后会有修改,所以我们用BIT维护)

    now用来更新那些已经 过气 没有贡献的答案,这里「没有贡献的答案」指的是p[now].a<i的情况,就是p[now]的电视剧集数太小了,已经不会再有贡献了,由于p[i].a是单增的,因此now++,扫一遍即可。

    代码:

     1 //#include"bits/stdc++.h"
     2 #include<sstream>
     3 #include<iomanip>
     4 #include"cstdio"
     5 #include"map"
     6 #include"set"
     7 #include"cmath"
     8 #include"queue"
     9 #include"vector"
    10 #include"string"
    11 #include"cstring"
    12 #include"time.h"
    13 #include"iostream"
    14 #include"stdlib.h"
    15 #include"algorithm"
    16 
    17 #define db double
    18 #define ll long long
    19 #define vec vector<ll>
    20 #define mt  vector<vec>
    21 #define ci(x) scanf("%d",&x)
    22 #define cd(x) scanf("%lf",&x)
    23 #define cl(x) scanf("%lld",&x)
    24 #define pi(x) printf("%d
    ",x)
    25 #define pd(x) printf("%f
    ",x)
    26 #define pl(x) printf("%lld
    ",x)
    27 //#define rep(i, x, y) for(int i=x;i<=y;i++)
    28 #define rep(i, n) for(int i=0;i<n;i++)
    29 const int N = 1e6 + 5;
    30 const int mod = 1e9 + 7;
    31 const int MOD = mod - 1;
    32 const int inf = 0x3f3f3f3f;
    33 const db PI = acos(-1.0);
    34 const db eps = 1e-10;
    35 using namespace std;
    36 ll ans;
    37 int n, now, a[N],bit[N];
    38 struct node {
    39     int a, i;
    40     bool operator<(node &xx) const {
    41         return a < xx.a;
    42     }
    43 } p[N];
    44 int read() {
    45     char ch = getchar();
    46     int ret = 0;
    47     for (; !isdigit(ch); ch = getchar());
    48     for (; isdigit(ch); ch = getchar())
    49         ret = (ret << 3) + (ret << 1) + ch - 48;
    50     return ret;
    51 }
    52 void add(int x, int c) { for (; x <= n + 1; x += x & -x)bit[x] += c; }
    53 int sum(int x) {
    54     int ret = 0;
    55     for (; x; x -= x & -x)
    56         ret += bit[x];
    57     return ret;
    58 }
    59 int main() {
    60     n = read();
    61     now = 1;
    62     for (int i = 1; i <= n; i++)
    63         a[i] = min(read(), n), p[i].a = a[i], p[i].i = i, add(i, 1);
    64     sort(p + 1, p + n + 1);
    65     for (int i = 1; i <= n; i++) {
    66         while (now <= n && p[now].a < i)add(p[now++].i, -1);//去掉无贡献的值
    67         ans += sum(a[i]);
    68         if (a[i] >= i) ans--;//(i,j) i=j的情况去掉
    69     }
    70     cout << ans / 2 << endl;
    71     return 0;
    72 }
  • 相关阅读:
    工具资源系列之给 windows 虚拟机装个 mac
    工具资源系列之 github 上各式各样的小徽章从何而来?
    php 学习笔记之日期时间操作一箩筐
    2018-12-03 VS Code英汉词典插件v0.0.7-尝试词性搭配
    2018-11-29 VS Code英汉词典插件v0.0.6-改为TS实现, 加测试
    2018-11-27 中文代码示例之Programming in Scala笔记第七八章
    2018-11-23 手工翻译Vue.js源码:尝试重命名标识符与文本
    2018-11-21 手工翻译Vue.js源码第一步:14个文件重命名
    2018-11-16 中文代码示例之Programming in Scala笔记第四五六章
    2018-11-13 中文代码示例之Programming in Scala学习笔记第二三章
  • 原文地址:https://www.cnblogs.com/mj-liylho/p/8759276.html
Copyright © 2011-2022 走看看