牛客小白月赛17 G 区间求和
2024-09-02 08:55:59
题意:
题解:
原本想着使用暴力方法:
1 #include<stdio.h>
2 #include<string.h>
3 #include<iostream>
4 #include<algorithm>
5 #include<map>
6 using namespace std;
7 typedef long long ll;
8 const int maxn=1e5+5;
9 const int mod=26;
10 int v[maxn],w[maxn];
11 int main()
12 {
13 int n,m;
14 scanf("%d%d",&n,&m);
15 for(int i=1;i<=n;++i)
16 {
17 scanf("%d",&v[i]);
18 //sum[i]=sum[i-1]+v[i];
19 }
20 while(m--)
21 {
22 int l,r,ans=0;
23 memset(w,0,sizeof(w));
24 scanf("%d%d",&l,&r);
25 for(int i=l;i<=r;++i)
26 {
27 ans=ans+w[v[i]]*v[i];
28 w[v[i]]++;
29 ans=ans+w[v[i]]*v[i];
30 }
31 printf("%d\n",ans);
32 }
33 return 0;
34 }
但是对每一次的询问都对应一次区间[l,r]的遍历,最大复杂度就是1e5*1e5(还以为数据会水过)
这个时候就要使用莫队算法(优雅的暴力)来解决了
莫队算法就是先分块,再所有询问的区间按某种方式进行排序,一个一个区间的找结果。具体看代码
以多少分一块看具体情况,这个不固定
代码:
1 #include<stdio.h>
2 #include<string.h>
3 #include<iostream>
4 #include<algorithm>
5 #include<map>
6 using namespace std;
7 typedef long long ll;
8 const int maxn=1e5+5;
9 const int mod=26;
10 const int block=300;
11 ll w[maxn],ans,v[maxn],sum[maxn];
12 struct shudui
13 {
14 ll l,r,id;
15 bool operator<(const shudui x)const //<号代表从大到小排序
16 {
17 if(l/block==x.l/block)
18 return r<x.r;
19 else return l/block<x.l/block;
20 }
21 }m[maxn];
22 ll n,k;
23 void add(ll i)
24 {
25 ans=ans+w[v[i]]*v[i]; //w存这个数字出现的次数
26 w[v[i]]++;
27 ans=ans+w[v[i]]*v[i]; //如果一个数字出先2次,那么可以第一次遇见它只加上它
28 } //再一次遇见再加一次。比如3出现2次
29 void del(ll i) //第一次ans=3
30 {
31 ans=ans-w[v[i]]*v[i]; //第二次ans+3+w[3]*3 ==3*2+3*2(最后的结果)
32 w[v[i]]--;
33 ans=ans-(w[v[i]]*v[i]);
34 }
35 int main()
36 {
37 scanf("%lld%lld",&n,&k);
38 for(ll i=1;i<=n;++i)
39 {
40 scanf("%lld",&v[i]);
41 }
42 for(ll i=1;i<=k;++i)
43 {
44 scanf("%lld%lld",&m[i].l,&m[i].r);
45 m[i].id=i;
46 }
47 sort(m+1,m+1+k);
48 ll l=0,r=0;
49 ans=0;
50 for(ll i=1;i<=k;++i)
51 {
52 while(l<m[i].l)
53 del(l),l++;
54 while(l>m[i].l)
55 add(--l);
56 while(r>m[i].r)
57 del(r),r--;
58 while(r<m[i].r)
59 add(++r);
60 sum[m[i].id]=ans;
61 }
62 for(ll i=1;i<=k;++i)
63 {
64 printf("%lld\n",sum[i]);
65 }
66 return 0;
67 }
最新文章
- 学写js Calender控件
- Catalan数应用整理
- Gamma校正与线性空间
- Java基础之打印万年历
- linux中创建gpio节点
- ListView缓存机制踩过的坑
- PHP搜索MYSQL数据库加分页浏览小结
- JS读取client端的文件的代码片段
- POJ 3175 Finding Bovine Roots (暴力求解)
- Toad for Oracle 授权权限
- PHP页面中文乱码问题
- Android:源码环境下移植第三方的apk内置到ROM(System Image)中
- QT---系统托盘图标不显示原因
- 温故而知新之java的collection framwork
- 3P - Snooker
- Codeforces.600E.Lomsat gelral(dsu on tree)
- 关于那个.get .post .ajax ztree 还有后台servlet传递数据
- LeetCode题解之Palindromic Substrings
- vue-element-table-js去重合并单元格解析【实战需求】
- 如何使用Java执行cmd命令
热门文章
- 配置 Docker 镜像加速源地址
- ORA-12560错误
- VPS下环境漏洞部署
- 【Azure Developer】已发布好的.NET Core项目文件如何打包为Docker镜像文件
- 前端面试之JavaScript的基本数据类型!
- 记一次压测问题定位:connection reset by peer,TCP三次握手后服务端发送RST_网络_c359719435的专栏-CSDN博客 https://blog.csdn.net/c359719435/article/details/80300433
- By default, the connection will be closed if the proxied server does not transmit any data within 60 seconds.
- VMware 虚拟机逃逸漏洞
- 二进制GCD
- 数位DP笔记