首页 > 其他分享 >数状数组

数状数组

时间:2023-12-01 15:22:05浏览次数:32  
标签:10 数状 int res scanf while 数组

1.循环右移,老套路了,直接开2n数组

然后利用树状数组进行区间求和和单点修改,每次减去之前以及出现过的值

Problem - E - Codeforces

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 1e6 + 10;
 5 
 6 int t;
 7 int c[N * 2];
 8 int sum(int x)
 9 {
10     int res = 0;
11      while(x){
12          res += c[x];
13          x -= x & -x;
14      }
15      return res;
16 } 
17 void add(int x,int v,int n)
18 {
19     while(x <= n)
20     {
21         c[x] += v;
22         x += x & -x;
23     }
24 }
25 struct Node{
26     int x,id;
27 };
28 vector<Node> b[N * 2];
29 int a[N];
30 int ans[N];
31 int main()
32 {
33     scanf("%d", &t);
34     while(t -- )
35     {
36         int n;
37         scanf("%d", &n);
38         for(int i = 1; i <= 2 * n;i ++) c[i] = 0,b[i].clear();
39         for(int i = 1; i <= n; i ++){ //对右端点进行排序 
40             scanf("%d", &a[i]);
41             if(i <= a[i]){ //b数组的存的右端点的值是唯一的
42                 b[a[i]].push_back({i,a[i]}); //右边a[i] 表示询问的编号
43                 b[a[i] + n].push_back({i + n,a[i]});
44             }else {
45                 b[a[i] + n].push_back({i,a[i]}); //i表示左端点,a[i] + n 表示右端点
46             }
47         }
48         for(int q = 1; q <= 2 * n; q ++){
49             for(auto [x, id] : b[q]){
50                 if(x <= n) ans[id] = q - x - (sum(q - 1) - sum(x));
51                 add(x,1,2 * n);
52             }
53         }
54         for(int i = 1; i <= n; i ++) printf("%d ",ans[i]);
55         cout << endl;
56     }
57     return 0;
58 }
Code

 

标签:10,数状,int,res,scanf,while,数组
From: https://www.cnblogs.com/rw666/p/17869775.html

相关文章

  • 【差分数组】我的日程安排表
    一、我的日程安排表I题目链接:我的日程安排表I实现一个MyCalendar类来存放你的日程安排。如果要添加的日程安排不会造成重复预订,则可以存储这个新的日程安排。当两个日程安排有一些时间上的交叉时(例如两个日程安排都在同一时间内),就会产生重复预订。日程可以用一对整数......
  • 【C语言】【二级】移动一维数组中的内容;若数组中有n个整数,要求把下标从0到p的数组元
    题目请编写函数fun,函数的功能是:移动一维数组中的内容;若数组中有n个整数,要求把下标从0到p(含p,p小于等于n-1)的数组元素平移到数组的最后。例如,一维数组中的原始内容为:1,2,3,4,5,6,7,8,9,10;p的值为3。移动后,一维数组中的内容应为:5,6,7,8,9,10,1,2,3,4。考点一维数组、......
  • 通过Span实现高性能数组,实例解析
    Span<T>是C#7.2引入的一个强大的数据结构,用于表示内存中的一块连续数据。它可以用于实现高性能的数组操作,而无需额外的内存分配。在本文中,我将详细介绍如何使用Span<T>来实现高性能数组操作,并提供一些示例代码来说明其用法。什么是Span?Span<T>是System.Memory命名空间......
  • 指针数组和数组指针
    intmain(){int*p1[10];int(*p2)[10];return0;}首先要知道,[]优先级是要高于*号。int*p1[10],p1优先和数组结合,那么此时p1就是一个数组,里面存放的内容都是指针类型,所以p1是一个数组,里面存放的内容是指针的地址,叫指针数组。int(*p2)[10],在这里*号优先......
  • Java Learning Day3 数组
    System.out.print;  System.out.println;每输出一次就会换行Integer.parseInt字符串转intDouble.parseDouble字符串转double数组存储结构连续,存储元素类型相同,随机访问 JVMJVM栈:JVM栈正是java中方法执行时所占有的空间、局部变量会存于栈帧中堆:堆是JVM内存中最大......
  • 数组对比大小 vue3
    lett_data=sortByKey(pz_data.data,"yield_per_mu");//array:当前数组//key:数组中需要比较大小的值exportconstsortByKey=(array:any,key:any)=>{returnarray.sort(function(a:any,b:any){varx=b[key];vary=a[key];returnx&l......
  • 【DFS深度优先遍历】给定一个数组,从第一个开始,正好走到数组最后,所使用的最少步骤数
    题目描述给定一个数组,从第一个开始,正好走到数组最后,所使用的最少步骤数。要求:第一步从第一元素开始,第一步小于<len/2(len为数组的长度)。从第二步开始,只能以所在成员的数字走相应的步数,不能多也不能少,如果目标不可达返回-1,输出最少的步骤数,不能往回走。输入759426835......
  • 枚举类的values()方法 枚举类有一个values()方法,这个方法可以将枚举类转换成一个枚举
    枚举类的values()方法枚举类有一个values()方法,这个方法可以将枚举类转换成一个枚举类型的数组,转换成数组之后我们就可以通过下标来访问我们的枚举类中的值枚举类中的元素是无法通过下标值来访问的,如果你想指定访问枚举类中的某个值,你只能直接写出它们的值,除此之外,别无他法。但......
  • 如何理解C语言中“数组名就是指针”
    定义一个数组:inta[5]={1,2,3,4,5};访问元素5可以通过以下形式的代码:a[4];/*下标运算符,可理解为数组的访问形式*/*(a+4);/*指针的加法运算和解引用,可理解为指针的引用形式*/实际上这两种访问形式是等价的,即X[m]=*(X+m)这里不妨再拓展一下,根据加法交换律,交换两个加数的......
  • day1数组理论基础,704. 二分查找,27. 移除元素
    数组理论基础,704.二分查找,27.移除元素1数组理论基础1.1数组概念定义:存放在连续内存空间上的相同类型数据的集合。特点:1.数组中数据类型相同2.数组所占空间连续1.2数组创建2704.二分查找给定一个n个元素有序的(升序)整型数组nums和一个目标值target,写一个函数......